编程实战:类C语法的编译型脚本解释器(系列)

        “脚本”始终是个具有独特魅力的领域,能够随时方便地解决一些问题,但脚本的随意性同时带来别的问题,所以脚本始终属于让人又爱又恨的存在。

        很多大型系统都会嵌入一些小型的解释器,用来让用户亲自编写简单的逻辑规则。不幸的是,每个解释器都是不同的,带有一些专用功能,而源代码又很精巧,递归递归再递归,然后没看懂就正确了……想加功能不知道怎么做……

        这种脚本还有个问题是,如果语法错了,结果就是错了,为什么错了——自己去想!

        所以琢磨了一段时间之后,我想,算了吧,不如重新写个呢。所以我就写了一个类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写了一个演示程序:

编程实战:类C语法的编译型脚本解释器(系列)_第1张图片

二、内置函数

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

        看得出来,为了测试写了很多辅助东西。 

六、设计与实现

        后续文章:

        (待续)

(这里是结束)

你可能感兴趣的:(C语法的预编译脚本解释器,c语言,开发语言,脚本解释器,C++)