“脚本”始终是个具有独特魅力的领域,能够随时方便地解决一些问题,但脚本的随意性同时带来别的问题,所以脚本始终属于让人又爱又恨的存在。
很多大型系统都会嵌入一些小型的解释器,用来让用户亲自编写简单的逻辑规则。不幸的是,每个解释器都是不同的,带有一些专用功能,而源代码又很精巧,递归递归再递归,然后没看懂就正确了……想加功能不知道怎么做……
这种脚本还有个问题是,如果语法错了,结果就是错了,为什么错了——自己去想!
所以琢磨了一段时间之后,我想,算了吧,不如重新写个呢。所以我就写了一个类C语法的脚本解释器,因为C语言运维人员都会一点,脚本是预先编译的,不会把语法错误延迟到运行时,因为自己写,所以和系统其他部分可以轻松整合,大家都很赞同我的想法(其实他们根本不在乎我怎么做好吧!他们只在乎我是不是把功能实现了)。
实际上脚本有很多现成的可用,甚至于C++脚本都有(很大一个项目,有个官网的),如果可以,选择现成的当然没问题,如果有别的动机,搞自己也没关系。
本系列介绍我的这个脚本实现。
目录
一、功能介绍
二、内置函数
三、代码示例
四、预编译
五、测试用例
六、设计与实现
这是内置的功能介绍的内容:
带有预编译功能的脚本解释器 以简单C++语法为基础 做了少量扩展
未支持的关键字、运算符全部保留,不可用做标识符
已经支持的语法:
语句:if else return {} for do while break continue;
转义字符:C++标准
注释://到行尾
增加的关键字:string
强数据类型:
整数:int long
浮点数:float double
字符串:string
数值常量:C++标准
字符串常量:双引号单引号均可
不允许数值和字符串的自动化转换
算术运算 + - * / % ++ --
逻辑运算 ! > < >= <= == !=
关系运算 && ||
赋值运算 = += -= *= /= %=
逗号运算 ,
+可用作字符串连接
++ --前缀每个变量只能用一次,后缀只能独立使用
每个声明语句只能声明一个变量,可初始化
for语句的初始化子句可以声明变量
不允许变量覆盖(不同的同级块内变量可以同名)
最后执行的表达式结果作为返回值,包括循环的判断语句
空语句返回空
if语句若无匹配语句返回空
break continue不影响返回值
声明语句返回变量值
复杂逻辑下应使用return语句
不打算支持的语法:
源代码的三字母序列
?: 位运算 * & sizeof [] -> . (类型)
switch goto
内部函数支持常用的数值转换和字符串操作
支持函数,函数只能使用之前已经定义的全局变量和环境变量,参数都是值传递,不支持默认值
大致上讲,就是一个C语言的基础部分加上string,重点是支持函数接口,可以自己扩展函数。实际中的主要目的就是用函数接口把系统的其它功能接进来。
基本算术运算和逻辑运算都支持,常见数学和字符串函数已经内置函数支持。
这个代码可以在Unix/Linux和Windows上运行,我在win上用MFC写了一个演示程序:
abs : 返回值 DOUBLE
绝对值,1个参数,参数必须是数值
ceil : 返回值 DOUBLE
向上取整,1个参数,参数必须是数值
floor : 返回值 DOUBLE
向下取整,1个参数,参数必须是数值
max : 返回值 DOUBLE
取最大值,1-N个参数,参数必须是数值
min : 返回值 DOUBLE
取最小值,1-N个参数,参数必须是数值
nullfun : 返回值 NULLVARIABLE
测试用函数,用户不可调用
round : 返回值 LONG
四舍五入,1个参数,参数必须是数值,负数向0舍入,-1.2返回-1,-1.8返回-2
strcat : 返回值 STRING
字符串连接,2个参数,参数必须是字符串
strcmp : 返回值 LONG
字符串比较,2个参数,参数必须是字符串
stricmp : 返回值 LONG
字符串忽略大小写比较,2个参数,参数必须是字符串
strlen : 返回值 LONG
字符串长度,1个参数,参数必须是字符串
strncmp : 返回值 LONG
字符串部分比较,3个参数
参数1 字符串
参数2 字符串
参数3 整数
strnicmp : 返回值 LONG
字符串忽略大小写部分比较,3个参数
参数1 字符串
参数2 字符串
参数3 整数
strstr : 返回值 LONG
查找子串,2个参数,参数必须是字符串,返回参数2在参数1中出现的位置,若没找到则返回-1
substr : 返回值 STRING
获取子串,2-3个参数,参数必须是数值,参数2为开始位置,参数3为字符数,省略参数3则一直取到字符串结束
to_double : 返回值 DOUBLE
转换为浮点数,一个参数,任意类型
to_long : 返回值 LONG
转换为整数,一个参数,任意类型
to_string : 返回值 STRING
转换为字符串,一个参数,任意类型
内置函数可以作为函数接口的示例代码。
示例1 简单表达式:
123+4.5*3-max(1,2,3,0)
示例2 简单逻辑:
if(12>5)12+5;else 12*5
示例3 复杂逻辑,注意确保每个执行路径都返回有意义的结果:
int i;//int与long同义
double d=1.5+max(1,2,3);//float与double同义
string s=to_string(d);
do //do循环
{
++i;
}while(i<10);
while(i>0) //while循环
{
i-=d;
}
for(i=0;i<5;++i) //for循环
{
if(strlen(s+'abc')>=3) //if语句 if()...或if()...else...或if()...else if()...else...可以有多个else if
{
continue;
}
else
{
break;
}
}
return i+d;
看得出来,与一个C函数的函数体非常相似,所以学过C的写起来毫无障碍。
脚本在执行前需要编译成内部结构,从而发现语法错误。至于是不是更高效?我没有太关心,毕竟首先要解决的是功能实现。
对于后台作业系统,提前发现问题很重要。
作为一个良好的编程习惯,把测试用例和源码保存在一起很有用。
测试用例如下:
CTestCase()
{
AddCase("return 5;", "5");
AddCase("return -5;", "-5");
AddCase("return 5.6", "5.6");
AddCase("return 5.", "5");
AddCase("return .6", ".6");
AddCase("int i=5;return ++i", "6");
AddCase("int i=5;return i++", "5");
AddCase("int i=5;return --i", "4");
AddCase("int i=5;return i--", "5");
AddCase("return", "");
AddCase("return;", "");
AddCase("x", "5");
AddCase("y", "10.5");
AddCase("z", "abc");
AddCase("return max(x,y)", "10.5");
AddCase("int i=2.3;i+=1,i+=1;max(i+7,5);", "11");
AddCase("int i=2.3;i+=1,i+=1;max(i+7,5);int _;b ;return a.b", "error");
AddCase("int x;return 1;", "error");
AddCase("int i;if(1)int i;else int i;return 1;", "error");
AddCase("if(1)int i=2;else int i;return i;", "error");
AddCase("if(0){int i=2;return i;}else{ int i=3;return i;}", "3");
AddCase("if(1){int i=2;return i;}else{ int i=3;return i;}", "2");
AddCase("int i=1;if(i<2)return 3;else return 4", "3");
AddCase("int i=2;if(i<2)return 3;else return 4", "4");
AddCase("for(int i=2;i<5;++i){return i;}", "2");
AddCase("int i=0;for(;i<5;++i){}return i;", "5");
AddCase("int i=1;for(int i=2;i<5;++i){int i=10;return i;}", "error");
AddCase("for(int i=2;i<5;++i){int i=10;return i;}", "error");
AddCase("for(int i=2;i<5;++i){int j=10;return i;}", "2");
AddCase("int a;int f(){return 3;};int b;for(int i=2;i<5;++i){int j=10;return f();}", "3");
AddCase("int a;int f(int a,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}", "error");
AddCase("int a;int f(int x,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}", "error");
AddCase("int a;int f(int aa,int b){return b;};int f(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}", "error");
AddCase("int a;int f(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}", "2");
}
测试结果是这样的:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 1 : return 5;
脚本测试用例成功,预期结果[5]实际结果[5]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 2 : return -5;
脚本测试用例成功,预期结果[-5]实际结果[-5]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 3 : return 5.6
脚本测试用例成功,预期结果[5.6]实际结果[5.5999999999999996447286321199499070644378662109375]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 4 : return 5.
脚本测试用例成功,预期结果[5]实际结果[5.]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 5 : return .6
脚本测试用例成功,预期结果[.6]实际结果[0.59999999999999997779553950749686919152736663818359375]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 6 : int i=5;return ++i
脚本测试用例成功,预期结果[6]实际结果[6]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 7 : int i=5;return i++
脚本测试用例成功,预期结果[5]实际结果[5]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 8 : int i=5;return --i
脚本测试用例成功,预期结果[4]实际结果[4]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 9 : int i=5;return i--
脚本测试用例成功,预期结果[5]实际结果[5]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 10 : return
脚本测试用例成功,预期结果[]实际结果[]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 11 : return;
脚本测试用例成功,预期结果[]实际结果[]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 12 : x
脚本测试用例成功,预期结果[5]实际结果[5]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 13 : y
脚本测试用例成功,预期结果[10.5]实际结果[10.5]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 14 : z
脚本测试用例成功,预期结果[abc]实际结果[abc]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 15 : return max(x,y)
脚本测试用例成功,预期结果[10.5]实际结果[10.5]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 16 : int i=2.3;i+=1,i+=1;max(i+7,5);
脚本测试用例成功,预期结果[11]实际结果[11.]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 17 : int i=2.3;i+=1,i+=1;max(i+7,5);int _;b ;return a.b
来自文件Script2.h的行817的出错信息:出错脚本:
int i=2.3;i+=1,i+=1;max(i+7,5);int _;b ;return a.b
出错位置37
.....................................b ;return a.b
错误信息:
未声明的变量
----------------------------
脚本:
int i=2.3;i+=1,i+=1;max(i+7,5);int _;b ;return a.b
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD int
001 004 IDENTIFIER i
002 005 OPERATOR =
003 006 NUMBER 2.3
004 009 DELIMITER ;
005 010 IDENTIFIER i
006 011 OPERATOR +=
007 013 NUMBER 1
008 014 OPERATOR ,
009 015 IDENTIFIER i
010 016 OPERATOR +=
011 018 NUMBER 1
012 019 DELIMITER ;
013 020 IDENTIFIER max
014 023 OPERATOR (
015 024 IDENTIFIER i
016 025 OPERATOR +
017 026 NUMBER 7
018 027 OPERATOR ,
019 028 NUMBER 5
020 029 OPERATOR )
021 030 DELIMITER ;
022 031 KEYWORD int
023 035 IDENTIFIER _
024 036 DELIMITER ;
025 037 IDENTIFIER b
026 039 DELIMITER ;
027 040 KEYWORD return
028 047 IDENTIFIER a
029 048 OPERATOR .
030 049 IDENTIFIER b
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 009 语句类型 DECLARE : int i=2.3;
表达式:
000 004 表达式类型 CONSTANT 结果类型 LONG : int i
i 变量类型 LONG : 0
--------------------------------------------------------------------------------
010 019 语句类型 EXPRESSION : i+=1,i+=1;
表达式:
010 018 表达式类型 OPERATION 结果类型 LONG : i+=1,i+=1
010 013 表达式类型 OPERATION 结果类型 LONG : i+=1
010 010 表达式类型 VARIABLE 结果类型 LONG : i
变量类型 LONG : 0
+=
013 013 表达式类型 DEFINE 结果类型 LONG : 1
变量类型 LONG : 1
,
015 018 表达式类型 OPERATION 结果类型 LONG : i+=1
015 015 表达式类型 VARIABLE 结果类型 LONG : i
变量类型 LONG : 0
+=
018 018 表达式类型 DEFINE 结果类型 LONG : 1
变量类型 LONG : 1
--------------------------------------------------------------------------------
020 030 语句类型 EXPRESSION : max(i+7,5);
表达式:
020 029 表达式类型 PLUGIN 结果类型 DOUBLE : max(i+7,5)
插件名: max 参数:
024 026 表达式类型 OPERATION 结果类型 LONG : i+7
024 024 表达式类型 VARIABLE 结果类型 LONG : i
变量类型 LONG : 0
+
026 026 表达式类型 DEFINE 结果类型 LONG : 7
变量类型 LONG : 7
028 028 表达式类型 DEFINE 结果类型 LONG : 5
常量类型 LONG : 5
--------------------------------------------------------------------------------
031 035 语句类型 DECLARE : int _
表达式:
031 035 表达式类型 CONSTANT 结果类型 LONG : int _
_ 变量类型 LONG : 0
--------------------------------------------------------------------------------
036 036 语句类型 NULLSENTENCE : ;
--------------------------------------------------------------------------------
037 039 语句类型 EXPRESSION : b ;
表达式:
037 038 表达式类型 VARIABLE 结果类型 NULLVARIABLE: b
b
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
3 : i : 变量类型 LONG : 0
4 : _ : 变量类型 LONG : 0
参数:
局部变量:
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行817的出错信息:出错脚本:
int i=2.3;i+=1,i+=1;max(i+7,5);int _;b ;return a.b
出错位置37
.....................................b ;return a.b
错误信息:
未声明的变量
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 18 : int x;return 1;
来自文件Script2.h的行861的出错信息:出错脚本:
int x;return 1;
出错位置0
int x;return 1;
错误信息:
添加变量失败
----------------------------
脚本:
int x;return 1;
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD int
001 004 IDENTIFIER x
002 005 DELIMITER ;
003 006 KEYWORD return
004 013 NUMBER 1
005 014 DELIMITER ;
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 004 语句类型 DECLARE : int x
表达式:
000 004 表达式类型 CONSTANT 结果类型 NULLVARIABLE: int x
x 变量类型 LONG : 0
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
参数:
局部变量:
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行861的出错信息:出错脚本:
int x;return 1;
出错位置0
int x;return 1;
错误信息:
添加变量失败
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 19 : int i;if(1)int i;else int i;return 1;
来自文件Script2.h的行861的出错信息:出错脚本:
int i;if(1)int i;else int i;return 1;
出错位置11
...........int i;else int i;return 1;
错误信息:
添加变量失败
----------------------------
脚本:
int i;if(1)int i;else int i;return 1;
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD int
001 004 IDENTIFIER i
002 005 DELIMITER ;
003 006 KEYWORD if
004 008 OPERATOR (
005 009 NUMBER 1
006 010 OPERATOR )
007 011 KEYWORD int
008 015 IDENTIFIER i
009 016 DELIMITER ;
010 017 KEYWORD else
011 022 KEYWORD int
012 026 IDENTIFIER i
013 027 DELIMITER ;
014 028 KEYWORD return
015 035 NUMBER 1
016 036 DELIMITER ;
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 004 语句类型 DECLARE : int i
表达式:
000 004 表达式类型 CONSTANT 结果类型 LONG : int i
i 变量类型 LONG : 0
--------------------------------------------------------------------------------
005 005 语句类型 NULLSENTENCE : ;
--------------------------------------------------------------------------------
006 015 语句类型 IF : if(1)int i
表达式:
009 009 表达式类型 DEFINE 结果类型 LONG : 1
常量类型 LONG : 1
子语句:
011 015 语句类型 DECLARE : int i
表达式:
011 015 表达式类型 CONSTANT 结果类型 NULLVARIABLE: int i
i 变量类型 LONG : 0
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
3 : i : 变量类型 LONG : 0
参数:
局部变量:
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行861的出错信息:出错脚本:
int i;if(1)int i;else int i;return 1;
出错位置11
...........int i;else int i;return 1;
错误信息:
添加变量失败
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 20 : if(1)int i=2;else int i;return i;
来自文件Script2.h的行817的出错信息:出错脚本:
if(1)int i=2;else int i;return i;
出错位置31
...............................i;
错误信息:
未声明的变量
----------------------------
脚本:
if(1)int i=2;else int i;return i;
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD if
001 002 OPERATOR (
002 003 NUMBER 1
003 004 OPERATOR )
004 005 KEYWORD int
005 009 IDENTIFIER i
006 010 OPERATOR =
007 011 NUMBER 2
008 012 DELIMITER ;
009 013 KEYWORD else
010 018 KEYWORD int
011 022 IDENTIFIER i
012 023 DELIMITER ;
013 024 KEYWORD return
014 031 IDENTIFIER i
015 032 DELIMITER ;
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 022 语句类型 IF : if(1)int i=2;else int i
表达式:
003 003 表达式类型 DEFINE 结果类型 LONG : 1
常量类型 LONG : 1
子语句:
005 012 语句类型 DECLARE : int i=2;
表达式:
005 009 表达式类型 CONSTANT 结果类型 LONG : int i
i 变量类型 LONG : 0
018 022 语句类型 DECLARE : int i
表达式:
018 022 表达式类型 CONSTANT 结果类型 LONG : int i
i 变量类型 LONG : 0
--------------------------------------------------------------------------------
023 023 语句类型 NULLSENTENCE : ;
--------------------------------------------------------------------------------
024 032 语句类型 RETURN : return i;
表达式:
031 031 表达式类型 VARIABLE 结果类型 NULLVARIABLE: i
i
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
参数:
局部变量:
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行817的出错信息:出错脚本:
if(1)int i=2;else int i;return i;
出错位置31
...............................i;
错误信息:
未声明的变量
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 21 : if(0){int i=2;return i;}else{ int i=3;return i;}
脚本测试用例成功,预期结果[3]实际结果[3]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 22 : if(1){int i=2;return i;}else{ int i=3;return i;}
脚本测试用例成功,预期结果[2]实际结果[2]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 23 : int i=1;if(i<2)return 3;else return 4
脚本测试用例成功,预期结果[3]实际结果[3]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 24 : int i=2;if(i<2)return 3;else return 4
脚本测试用例成功,预期结果[4]实际结果[4]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 25 : for(int i=2;i<5;++i){return i;}
脚本测试用例成功,预期结果[2]实际结果[2]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 26 : int i=0;for(;i<5;++i){}return i;
脚本测试用例成功,预期结果[5]实际结果[5]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 27 : int i=1;for(int i=2;i<5;++i){int i=10;return i;}
来自文件Script2.h的行861的出错信息:出错脚本:
int i=1;for(int i=2;i<5;++i){int i=10;return i;}
出错位置12
............int i=2;i<5;++i){int i=10;return i;}
错误信息:
添加变量失败
----------------------------
脚本:
int i=1;for(int i=2;i<5;++i){int i=10;return i;}
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD int
001 004 IDENTIFIER i
002 005 OPERATOR =
003 006 NUMBER 1
004 007 DELIMITER ;
005 008 KEYWORD for
006 011 OPERATOR (
007 012 KEYWORD int
008 016 IDENTIFIER i
009 017 OPERATOR =
010 018 NUMBER 2
011 019 DELIMITER ;
012 020 IDENTIFIER i
013 021 OPERATOR <
014 022 NUMBER 5
015 023 DELIMITER ;
016 024 OPERATOR ++
017 026 IDENTIFIER i
018 027 OPERATOR )
019 028 DELIMITER {
020 029 KEYWORD int
021 033 IDENTIFIER i
022 034 OPERATOR =
023 035 NUMBER 10
024 037 DELIMITER ;
025 038 KEYWORD return
026 045 IDENTIFIER i
027 046 DELIMITER ;
028 047 DELIMITER }
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 007 语句类型 DECLARE : int i=1;
表达式:
000 004 表达式类型 CONSTANT 结果类型 LONG : int i
i 变量类型 LONG : 0
--------------------------------------------------------------------------------
008 047 语句类型 FOR : for(int i=2;i<5;++i){int i=10;return i;}
表达式:
020 022 表达式类型 OPERATION 结果类型 NULLVARIABLE: i<5
020 020 表达式类型 VARIABLE 结果类型 NULLVARIABLE: i
变量类型 LONG : 0
<
022 022 表达式类型 DEFINE 结果类型 NULLVARIABLE: 5
变量类型 LONG : 5
024 026 表达式类型 OPERATION 结果类型 NULLVARIABLE: ++i
++
026 026 表达式类型 VARIABLE 结果类型 NULLVARIABLE: i
变量类型 LONG : 0
子语句:
012 019 语句类型 DECLARE : int i=2;
表达式:
012 016 表达式类型 CONSTANT 结果类型 NULLVARIABLE: int i
i 变量类型 LONG : 0
028 047 语句类型 BLOCK : {int i=10;return i;}
子语句:
029 037 语句类型 DECLARE : int i=10;
表达式:
029 033 表达式类型 CONSTANT 结果类型 NULLVARIABLE: int i
i 变量类型 LONG : 0
038 046 语句类型 RETURN : return i;
表达式:
045 045 表达式类型 VARIABLE 结果类型 NULLVARIABLE: i
变量类型 LONG : 0
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
3 : i : 变量类型 LONG : 0
参数:
局部变量:
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行861的出错信息:出错脚本:
int i=1;for(int i=2;i<5;++i){int i=10;return i;}
出错位置12
............int i=2;i<5;++i){int i=10;return i;}
错误信息:
添加变量失败
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 28 : for(int i=2;i<5;++i){int i=10;return i;}
来自文件Script2.h的行861的出错信息:出错脚本:
for(int i=2;i<5;++i){int i=10;return i;}
出错位置21
.....................int i=10;return i;}
错误信息:
添加变量失败
----------------------------
脚本:
for(int i=2;i<5;++i){int i=10;return i;}
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD for
001 003 OPERATOR (
002 004 KEYWORD int
003 008 IDENTIFIER i
004 009 OPERATOR =
005 010 NUMBER 2
006 011 DELIMITER ;
007 012 IDENTIFIER i
008 013 OPERATOR <
009 014 NUMBER 5
010 015 DELIMITER ;
011 016 OPERATOR ++
012 018 IDENTIFIER i
013 019 OPERATOR )
014 020 DELIMITER {
015 021 KEYWORD int
016 025 IDENTIFIER i
017 026 OPERATOR =
018 027 NUMBER 10
019 029 DELIMITER ;
020 030 KEYWORD return
021 037 IDENTIFIER i
022 038 DELIMITER ;
023 039 DELIMITER }
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 039 语句类型 FOR : for(int i=2;i<5;++i){int i=10;return i;}
表达式:
012 014 表达式类型 OPERATION 结果类型 LONG : i<5
012 012 表达式类型 VARIABLE 结果类型 LONG : i
变量类型 LONG : 0
<
014 014 表达式类型 DEFINE 结果类型 LONG : 5
变量类型 LONG : 5
016 018 表达式类型 OPERATION 结果类型 LONG : ++i
++
018 018 表达式类型 VARIABLE 结果类型 LONG : i
变量类型 LONG : 0
子语句:
004 011 语句类型 DECLARE : int i=2;
表达式:
004 008 表达式类型 CONSTANT 结果类型 LONG : int i
i 变量类型 LONG : 0
020 039 语句类型 BLOCK : {int i=10;return i;}
子语句:
021 029 语句类型 DECLARE : int i=10;
表达式:
021 025 表达式类型 CONSTANT 结果类型 NULLVARIABLE: int i
i 变量类型 LONG : 0
030 038 语句类型 RETURN : return i;
表达式:
037 037 表达式类型 VARIABLE 结果类型 NULLVARIABLE: i
变量类型 LONG : 0
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
参数:
局部变量:
3 : i : 变量类型 LONG : 0
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行861的出错信息:出错脚本:
for(int i=2;i<5;++i){int i=10;return i;}
出错位置21
.....................int i=10;return i;}
错误信息:
添加变量失败
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 29 : for(int i=2;i<5;++i){int j=10;return i;}
脚本测试用例成功,预期结果[2]实际结果[2]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 30 : int a;int f(){return 3;};int b;for(int i=2;i<5;++i){int j=10;return f();}
脚本测试用例成功,预期结果[3]实际结果[3]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 31 : int a;int f(int a,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
来自文件Script2.h的行2103的出错信息:出错脚本:
int a;int f(int a,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
出错位置16
................a,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
错误信息:
函数参数与全局变量或环境变量重名
----------------------------
脚本:
int a;int f(int a,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD int
001 004 IDENTIFIER a
002 005 DELIMITER ;
003 006 KEYWORD int
004 010 IDENTIFIER f
005 011 OPERATOR (
006 012 KEYWORD int
007 016 IDENTIFIER a
008 017 OPERATOR ,
009 018 KEYWORD int
010 022 IDENTIFIER b
011 023 OPERATOR )
012 024 DELIMITER {
013 025 KEYWORD return
014 032 IDENTIFIER b
015 033 DELIMITER ;
016 034 DELIMITER }
017 035 DELIMITER ;
018 036 KEYWORD int
019 040 IDENTIFIER b
020 041 DELIMITER ;
021 042 KEYWORD for
022 045 OPERATOR (
023 046 KEYWORD int
024 050 IDENTIFIER i
025 051 OPERATOR =
026 052 NUMBER 2
027 053 DELIMITER ;
028 054 IDENTIFIER i
029 055 OPERATOR <
030 056 NUMBER 5
031 057 DELIMITER ;
032 058 OPERATOR ++
033 060 IDENTIFIER i
034 061 OPERATOR )
035 062 DELIMITER {
036 063 KEYWORD int
037 067 IDENTIFIER j
038 068 OPERATOR =
039 069 NUMBER 10
040 071 DELIMITER ;
041 072 KEYWORD return
042 079 IDENTIFIER f
043 080 OPERATOR (
044 081 NUMBER 1
045 082 OPERATOR ,
046 083 NUMBER 2
047 084 OPERATOR )
048 085 DELIMITER ;
049 086 DELIMITER }
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------函数开始 f 全局变量个数 1 返回类型 LONG
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019E250
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数1
3 : a : 变量类型 LONG : 0
参数:
4 : a : 变量类型 LONG : 0
局部变量:
--------------------------------------------------------------------------------函数结束
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 004 语句类型 DECLARE : int a
表达式:
000 004 表达式类型 CONSTANT 结果类型 LONG : int a
a 变量类型 LONG : 0
--------------------------------------------------------------------------------
005 005 语句类型 NULLSENTENCE : ;
--------------------------------------------------------------------------------
006 005 语句类型 DECLARE :
表达式:
006 010 表达式类型 CONSTANT 结果类型 NULLVARIABLE: int f
f 变量类型 LONG : 0
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
3 : a : 变量类型 LONG : 0
参数:
局部变量:
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行2103的出错信息:出错脚本:
int a;int f(int a,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
出错位置16
................a,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
错误信息:
函数参数与全局变量或环境变量重名
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 32 : int a;int f(int x,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
来自文件Script2.h的行2103的出错信息:出错脚本:
int a;int f(int x,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
出错位置16
................x,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
错误信息:
函数参数与全局变量或环境变量重名
----------------------------
脚本:
int a;int f(int x,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD int
001 004 IDENTIFIER a
002 005 DELIMITER ;
003 006 KEYWORD int
004 010 IDENTIFIER f
005 011 OPERATOR (
006 012 KEYWORD int
007 016 IDENTIFIER x
008 017 OPERATOR ,
009 018 KEYWORD int
010 022 IDENTIFIER b
011 023 OPERATOR )
012 024 DELIMITER {
013 025 KEYWORD return
014 032 IDENTIFIER b
015 033 DELIMITER ;
016 034 DELIMITER }
017 035 DELIMITER ;
018 036 KEYWORD int
019 040 IDENTIFIER b
020 041 DELIMITER ;
021 042 KEYWORD for
022 045 OPERATOR (
023 046 KEYWORD int
024 050 IDENTIFIER i
025 051 OPERATOR =
026 052 NUMBER 2
027 053 DELIMITER ;
028 054 IDENTIFIER i
029 055 OPERATOR <
030 056 NUMBER 5
031 057 DELIMITER ;
032 058 OPERATOR ++
033 060 IDENTIFIER i
034 061 OPERATOR )
035 062 DELIMITER {
036 063 KEYWORD int
037 067 IDENTIFIER j
038 068 OPERATOR =
039 069 NUMBER 10
040 071 DELIMITER ;
041 072 KEYWORD return
042 079 IDENTIFIER f
043 080 OPERATOR (
044 081 NUMBER 1
045 082 OPERATOR ,
046 083 NUMBER 2
047 084 OPERATOR )
048 085 DELIMITER ;
049 086 DELIMITER }
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------函数开始 f 全局变量个数 1 返回类型 LONG
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019E250
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数1
3 : a : 变量类型 LONG : 0
参数:
4 : x : 变量类型 LONG : 0
局部变量:
--------------------------------------------------------------------------------函数结束
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 004 语句类型 DECLARE : int a
表达式:
000 004 表达式类型 CONSTANT 结果类型 LONG : int a
a 变量类型 LONG : 0
--------------------------------------------------------------------------------
005 005 语句类型 NULLSENTENCE : ;
--------------------------------------------------------------------------------
006 005 语句类型 DECLARE :
表达式:
006 010 表达式类型 CONSTANT 结果类型 NULLVARIABLE: int f
f 变量类型 LONG : 0
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
3 : a : 变量类型 LONG : 0
参数:
局部变量:
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行2103的出错信息:出错脚本:
int a;int f(int x,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
出错位置16
................x,int b){return b;};int b;for(int i=2;i<5;++i){int j=10;return f(1,2);}
错误信息:
函数参数与全局变量或环境变量重名
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 33 : int a;int f(int aa,int b){return b;};int f(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}
来自文件Script2.h的行2083的出错信息:出错脚本:
int a;int f(int aa,int b){return b;};int f(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}
出错位置42
..........................................(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}
错误信息:
函数重名
----------------------------
脚本:
int a;int f(int aa,int b){return b;};int f(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}
--------------------------------------------------------------------------------
单词(编号 起始字符位置):
--------------------------------------------------------------------------------
000 000 KEYWORD int
001 004 IDENTIFIER a
002 005 DELIMITER ;
003 006 KEYWORD int
004 010 IDENTIFIER f
005 011 OPERATOR (
006 012 KEYWORD int
007 016 IDENTIFIER aa
008 018 OPERATOR ,
009 019 KEYWORD int
010 023 IDENTIFIER b
011 024 OPERATOR )
012 025 DELIMITER {
013 026 KEYWORD return
014 033 IDENTIFIER b
015 034 DELIMITER ;
016 035 DELIMITER }
017 036 DELIMITER ;
018 037 KEYWORD int
019 041 IDENTIFIER f
020 042 OPERATOR (
021 043 KEYWORD int
022 047 IDENTIFIER aa
023 049 OPERATOR ,
024 050 KEYWORD int
025 054 IDENTIFIER b
026 055 OPERATOR )
027 056 DELIMITER {
028 057 KEYWORD return
029 064 IDENTIFIER b
030 065 DELIMITER ;
031 066 DELIMITER }
032 067 DELIMITER ;
033 068 KEYWORD int
034 072 IDENTIFIER b
035 073 OPERATOR =
036 074 NUMBER 3
037 075 DELIMITER ;
038 076 KEYWORD for
039 079 OPERATOR (
040 080 KEYWORD int
041 084 IDENTIFIER i
042 085 OPERATOR =
043 086 NUMBER 2
044 087 DELIMITER ;
045 088 IDENTIFIER i
046 089 OPERATOR <
047 090 NUMBER 5
048 091 DELIMITER ;
049 092 OPERATOR ++
050 094 IDENTIFIER i
051 095 OPERATOR )
052 096 DELIMITER {
053 097 KEYWORD int
054 101 IDENTIFIER j
055 102 OPERATOR =
056 103 NUMBER 10
057 105 DELIMITER ;
058 106 KEYWORD return
059 113 IDENTIFIER f
060 114 OPERATOR (
061 115 NUMBER 1
062 116 OPERATOR ,
063 117 NUMBER 2
064 118 OPERATOR )
065 119 DELIMITER ;
066 120 DELIMITER }
--------------------------------------------------------------------------------
函数:
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------函数开始 f 全局变量个数 1 返回类型 LONG
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
026 034 语句类型 RETURN : return b;
表达式:
033 033 表达式类型 VARIABLE 结果类型 LONG : b
变量类型 LONG : 0
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019E098
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数1
3 : a : 变量类型 LONG : 0
参数:
4 : aa : 变量类型 LONG : 0
5 : b : 变量类型 LONG : 0
局部变量:
--------------------------------------------------------------------------------函数结束
--------------------------------------------------------------------------------
语句(起始单词 结束单词):
--------------------------------------------------------------------------------
000 004 语句类型 DECLARE : int a
表达式:
000 004 表达式类型 CONSTANT 结果类型 LONG : int a
a 变量类型 LONG : 0
--------------------------------------------------------------------------------
005 005 语句类型 NULLSENTENCE : ;
--------------------------------------------------------------------------------
037 036 语句类型 DECLARE :
表达式:
037 041 表达式类型 CONSTANT 结果类型 NULLVARIABLE: int f
f 变量类型 LONG : 0
--------------------------------------------------------------------------------
变量:
--------------------------------------------------------------------------------
0019F184
环境变量:
0 : x : 变量类型 LONG : 5
1 : y : 变量类型 DOUBLE : 10.5
2 : z : 变量类型 STRING : abc
全局变量:有效数-1
3 : a : 变量类型 LONG : 0
参数:
局部变量:
--------------------------------------------------------------------------------
信息:
来自文件Script2.h的行2083的出错信息:出错脚本:
int a;int f(int aa,int b){return b;};int f(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}
出错位置42
..........................................(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}
错误信息:
函数重名
----------------------------
脚本测试用例成功,编译出错,符合预期
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
测试用例 34 : int a;int f(int aa,int b){return b;};int b=3;for(int i=2;i<5;++i){int j=10;return f(1,2);}
脚本测试用例成功,预期结果[2]实际结果[2]
全部用例测试结果正确 34
看得出来,为了测试写了很多辅助东西。
后续文章:
(待续)
(这里是结束)