1.1测试变量相关检查

1.1.1 测试1

  • 测试用例:变量重定义检查(作用域)
  1. program test(input,output);
    2. var test,input:integer; //test已定义为主程序名,input已定义为主程序参数
    3. a:real; //正确
    4. b:boolean; //正确
    5. c:array[1..5] of integer; //正确
    6. a:char; //a已定义为变量
    7. c:real; //c已定义为数组
    8.
    9. function fun(var a:integer;b:char):integer;
    10. var fun:integer; //fun已定义为当前所在的函数名
    11. a:real; //a已定义为当前所在函数的引用参数
    12. b:boolean; //b已定义为当前所在函数的传值参数
    13. begin
    14.
    15. end;
    16.
    17. procedure pro(var a:integer;b:char);
    18. var fun:integer; //正确
    19. pro:char; //pro已定义为当前所在的过程名
    20. a:real; //a已定义为当前所在过程的引用参数
    21. b:boolean; //b已定义为当前所在过程的传值参数
    22. begin
    23.
    24. end;
    25.
    26. begin
    27.
    28. end.
  • 预期结果

报变量已被定义为主程序名、函数参数、变量的错误

  • 测试结果
  1. [Duplicate defined error!] “test” has been defined as the name of program at Line 1.
    2. [Duplicate defined error!] “input” has been defined as a program parameter at Line 1.
    3. [Duplicate defined error!] “a” has already been defined as a normal variant at line 3.
    4. [Duplicate defined error!] “c” has already been defined as a array at line 5.
    5. [Duplicate defined error!] “fun” has already been defined as a (sub)program name at line 9.
    6. [Duplicate defined error!] “a” has already been defined as a var parameter at line 9.
    7. [Duplicate defined error!] “b” has already been defined as a value parameter at line 9.
    8. [Duplicate defined error!] “pro” has already been defined as a (sub)program name at line 17.
    9. [Duplicate defined error!] “a” has already been defined as a var parameter at line 17.
    10. [Duplicate defined error!] “b” has already been defined as a value parameter at line 17.
  • 分析

变量重定义检查(作用域),在同一个子函数内不能定义重复名字的变量、和子函数名相同的变量和与主函数中变量名相同的变量;但是可以定义与另一个子函数的函数名或变量名相同的变量

1.1.2 测试2

  • 测试用例:数组定义下界比上界大
  1. program test(input,output);
    2. var a:array[10..5] of integer; //下界比上界大
    3. b:array[5..10] of integer; //正确
    4. c:array[5..5] of integer; //正确
    5. begin
    6.
    7. end.
  • 预期结果

报数组下界比上界大的错误

  • 测试结果
  1. [Array range upsidedown error!] 1th range of array “a” have larger low bound and smaller high bound, which is 10 and 5.
  • 分析

数组定义下界比上界大,测试结果符合预期,语义分析程序继续运行

1.2测试常量相关检查

1.2.1 测试1

  • 测试用例:常量重定义
  1. program test(input,output);
    2. const test=1; //已定义为主程序名
    3. input=2; //已定义为主程序参数
    4. d=d; //右值未定义
    5. a=test; //右值非常量
    6. b=a; //右值未定义
    7. c=3; //正确
    8. a=b; //右值未定义
    9. c=c; //已定义为常量
    10.
    11. function fun(var a:integer;b:char):integer;
    12. const fun=-5; //已定义为当前所在函数名
    13. a=-10; //已定义为当前所在函数的引用参数
    14. b=a; //已定义为当前所在函数的传值参数
    15. begin
    16.
    17. end;
    18.
    19. procedure pro(var a:integer;b:char);
    20. const fun=3; //正确
    21. pro=-6; //已定义为当前所在过程名
    22. a=fun; //左值已定义为当前所在过程的引用参数
    23. b=pro; //左值已定义为当前所在过程的传值参数
    24. c=fun; //正确
    25. begin
    26.
    27. end;
    28.
    29. begin
    30.
    31. end.
  • 预期结果

报常量重复定义、常量右值未定义、常量右值非常量的错误

  • 测试结果
  1. [Duplicate defined error!] “test” has been defined as the name of program at Line 1.
    2. [Duplicate defined error!] “input” has been defined as a program parameter at Line 1.
    3. [Undefined identifier!] d has not been defined.
    4. [Symbol kinds mismatch!] “test” defined at line 1 is a (sub)program name but not a constant.
    5. [Undefined identifier!] a has not been defined.
    6. [Undefined identifier!] b has not been defined.
    7. [Duplicate defined error!] “c” has already been defined as a constant at line 7.
    8. [Duplicate defined error!] “fun” has already been defined as a (sub)program name at line 11.
    9. [Duplicate defined error!] “a” has already been defined as a var parameter at line 11.
    10. [Duplicate defined error!] “b” has already been defined as a value parameter at line 11.
    11. [Duplicate defined error!] “pro” has already been defined as a (sub)program name at line 19.
    12. [Duplicate defined error!] “a” has already been defined as a var parameter at line 19.
    13. [Duplicate defined error!] “b” has already been defined as a value parameter at line 19.
  • 分析

const c=1;c=c;这种是不对的,相当于常量c重复定义。测试结果符合预期,语义分析程序继续运行

1.2.2 测试2

  • 测试用例
  1. program test(input,output);
    2. const a=1; //正确
    3. b=a; //正确
    4. c=d; //右值未定义
    5. f=test; //右值是主程序名而不是常量
    6. f=input; //右值是主程序参数而不是常量
    7. var e:integer;
    8. g:array[1..5] of integer;
    9.
    10. procedure pro;
    11. begin
    12.
    13. end;
    14.
    15. function fun(var n:integer;m:char):integer;
    16. const a=e; //右值是变量而不是常量
    17. a=g; //右值是数组而不是常量
    18. a=fun; //右值是当前所在函数名而不是常量
    19. a=n; //右值是当前所在函数的引用参数而不是常量
    20. a=m; //右值是当前所在函数的传值参数而不是常量
    21. a=pro; //右值是子过程名而不是常量
    22. begin
    23.
    24. end;
    25.
    26. begin
    27.
    28. end.
  • 预期结果

报常量赋值语句右值未定义、右值不是常量的错误

  • 测试结果
  1. [Undefined identifier!] d has not been defined.
    2. [Symbol kinds mismatch!] “test” defined at line 1 is a (sub)program name but not a constant.
    3. [Symbol kinds mismatch!] “input” defined at line 1 is a parameter of program but not a constant.
    4. [Symbol kinds mismatch!] “e” defined at line 7 is a normal variant but not a constant.
    5. [Symbol kinds mismatch!] “g” defined at line 8 is a array but not a constant.
    6. [Symbol kinds mismatch!] “fun” defined at line 15 is a (sub)program name but not a constant.
    7. [Symbol kinds mismatch!] “n” defined at line 15 is a var parameter but not a constant.
    8. [Symbol kinds mismatch!] “m” defined at line 15 is a value parameter but not a constant.
    9. [Symbol kinds mismatch!] “pro” defined at line 10 is a procedure but not a constant.
  • 分析

测试结果符合预期,语义分析程序继续运行

1.2.3 测试3

  • 测试用例:常量传播
  1. program test(input,output);
    2. const a = 1.5;
    3. b = 3;
    4. c = -a;
    5. d = -b;
    6. e = 2;
    7. f = 5;
    8. g = -c;
    9. var h:integer;
    10. i:real;
    11. j:array[1..10] of integer;
    12. begin
    13. writeln(a);
    14. writeln(b);
    15. writeln(c);
    16. writeln(d);
    17. writeln(e);
    18. writeln(f);
    19. writeln(g);
    20. end.
  • 预期结果

语义分析程序不报错

  • 测试结果
  1. 1.500000
    2. 3
    3. -1.500000
    4. -3
    5. 2
    6. 5
    7. 1.500000
    语义分析程序没有报错,a.b.c.d.e.f.g的值如上
  • 分析

测试结果符合预期,语义分析程序继续运行

1.2.4 测试4

  • 测试用例:常量传播与常量表达式的计算
  1. program test(input,output);
    2. const a = 1.5;
    3. b = 3;
    4. c = -a;
    5. d = -b;
    6. e = 2;
    7. f = 5;
    8. g = -c;
    9. var h:integer;
    10. i:real;
    11. j:array[1..10] of integer;
    12. begin
    13. writeln(a);
    14. writeln(b);
    15. writeln(c);
    16. writeln(d);
    17. writeln(e);
    18. writeln(f);
    19. writeln(g);
    20. h := h / (2+3-f); //除0错误
    21. h := h mod (10 mod e); //除0错误
    22. h := h div (1 div d); //除0错误
    23. j[b+f]:=3; //正确
    24. writeln(j[b+f]); //正确
    25. j[-f]:=5; //越界
    26. end.
  • 预期结果

报除0和数组越界的错误

  • 测试结果
  1. [Divide zero error!] The value of expression “(2 + 3 - f)” is 0, which is the second operand of operation “/“.
    2. [Divide zero error!] The value of expression “(10 mod e)” is 0, which is the second operand of operation “mod“.
    3. [Divide zero error!] The value of expression “(1 div d)” is 0, which is the second operand of operation “div“.
    4. [Array range out of bound!] The value of expression “ - f” is -5, but the range of array “j” 0th index is 1 to 10.
  • 分析

测试结果符合预期,语义分析程序继续运行

1.2.5 测试5

  • 测试用例:常量左值引用
  1. program test(input,output);
    2. const a = 1.5;
    3. b = 3;
    4. c = -a;
    5. d = -b;
    6. e = 2;
    7. f = 5;
    8. g = -c;
    9. begin
    10. a:=3; //常量不能作为左值
    11. e:=6-3; //常量不能作为左值
    12. g:=b+c; //常量不能作为左值
    13. end.
  • 预期结果

报常量不能作为左值的错误

  • 测试结果
  1. [Constant as l-value error!] Costant “a” can’t be referenced as l-value.
    2. [Constant as l-value error!] Costant “e” can’t be referenced as l-value.
    3. [Constant as l-value error!] Costant “g” can’t be referenced as l-value.
  • 分析

常量左值引用错误,测试结果符合预期,语义分析程序继续运行

1.3 测试函数调用相关检查

1.3.1 测试1

  • 测试用例:函数调用未定义,标识符名不是函数
  1. program test(input,output);
    2. const f=5;
    3. var a,b:integer;
    4. c:array[1..5] of integer;
    5. procedure pro(var d:integer; e:char);
    6. begin
    7. a:=d(1); //d是当前所在过程的引用参数而不是函数
    8. a:=e(1); //e是当前所在过程的传值参数而不是函数
    9. a:=f(5); //f是常量而不是函数
    10. end;
    11.
    12. begin
    13. a:=fun(1); //fun未定义
    14. a:=b(1); //b是普通变量而不是函数
    15. a:=c(1); //c是数组而不是函数
    16. a:=test(1); //test是主程序名而不是函数
    17. a:=input(1); //input是主程序参数而不是函数
    18. a:=pro(1); //pro是子过程名而不是函数
    19. end.
  • 预期结果

报引用参数不是函数、传值参数不是函数、常量不是函数等错误

  • 测试结果
  1. [Symbol kinds mismatch!] “d” defined at line 5 is a var parameter but not a function.
    2. [Assign statement type mismatch!] Left “a” type is integer while right “d(1)” type is error.
    3. [Symbol kinds mismatch!] “e” defined at line 5 is a value parameter but not a function.
    4. [Assign statement type mismatch!] Left “a” type is integer while right “e(1)” type is error.
    5. [Symbol kinds mismatch!] “f” defined at line 2 is a constant but not a function.
    6. [Assign statement type mismatch!] Left “a” type is integer while right “f(5)” type is error.
    7. [Undefined identifier!] fun has not been defined.
    8. [Assign statement type mismatch!] Left “a” type is integer while right “fun(1)” type is error.
    9. [Symbol kinds mismatch!] “b” defined at line 3 is a normal variant but not a function.
    10. [Assign statement type mismatch!] Left “a” type is integer while right “b(1)” type is error.
    11. [Symbol kinds mismatch!] “c” defined at line 4 is a array but not a function.
    12. [Assign statement type mismatch!] Left “a” type is integer while right “c(1)” type is error.
    13. [Symbol kinds mismatch!] “test” defined at line 1 is a (sub)program name but not a function.
    14. [Assign statement type mismatch!] Left “a” type is integer while right “test(1)” type is error.
    15. [Symbol kinds mismatch!] “input” defined at line 1 is a parameter of program but not a function.
    16. [Assign statement type mismatch!] Left “a” type is integer while right “input(1)” type is error.
    17. [Symbol kinds mismatch!] “pro” defined at line 5 is a procedure but not a function.
    18. [Assign statement type mismatch!] Left “a” type is integer while right “pro(1)” type is error.
  • 分析

函数调用未定义,标识符名不是函数。测试结果符合预期,语义分析程序继续运行。

1.3.2 测试2

  • 测试用例:函数调用参数个数不对,类型不匹配
  1. program test(input,output);
    2. function fun(a,b,c:real):integer;//检查a,b,c是否已经为从小到大排序
    3. begin
    4. if a<=b then
    5. if b<=c then
    6. fun:=1;
    7. fun:=0
    8. end;
    9. begin
    10. writeln(fun); //参数缺失
    11. writeln(fun(1)); //参数缺失
    12. writeln(fun(1,’a’)); //参数缺失
    13. writeln(fun(1,2,3)); //正确
    14. writeln(fun(‘a’,1.1,3)); //参数类型不一致
    15. end.
  • 预期结果

报子函数参数缺失、参数类型不一致的问题

  • 测试结果
  1. [Function parameter number mismatch!] Function “fun” should have 3 but not 0 parameters.
    2. [Function parameter number mismatch!] Function “fun” should have 3 but not 1 parameters.
    3. [Function parameter number mismatch!] Function “fun” should have 3 but not 2 parameters.
    4. [Expression type error!] Expression “‘a’” used for 1th actual parameter of function call of “fun” should be real but not char.
  • 分析

函数调用参数个数不对,类型不匹配

1.3.3 测试3

  • 测试用例
  1. program test(input,output);
    2. function fun(a,b,c:real):integer;//检查a,b,c是否已经为从小到大排序
    3. begin
    4. if a<=b then
    5. if b<=c then
    6. fun:=1;
    7. fun:=0
    8. end;
    9. begin
    10. writeln(fun(1,2,3));
    11. writeln(fun(3,1,2));
    12. end.
  • 预期结果

语义分析程序不报错

  • 测试结果

语义分析程序不报错

  • 分析

测试结果符合预期,语义分析程序继续运行。

1.3.4 测试4

  • 测试用例:函数调用,表达式无法作为实参的情况
  1. program test(input,output);
    2. var a,b,c:integer;
    3. d:array[1..5] of integer;
    4.
    5. procedure pro;
    6. begin
    7.
    8. end;
    9.
    10. function fun(a,b,c:integer):integer;//检查a,b,c是否已经为从小到大排序
    11. begin
    12. if a<=b then
    13. if b<=c then
    14. fun:=1;
    15. fun:=0
    16. end;
    17. begin
    18. writeln(fun(a,b,c)); //正确
    19. writeln(fun(test,b,c)); //test是主程序名
    20. writeln(fun(input,b,c)); //input是主程序参数
    21. writeln(fun(pro,b,c)); //pro是子过程明
    22. writeln(fun(v,b,c)); //v未定义
    23. writeln(fun(1,b,c)); //正确
    24. writeln(fun(d[1],b,c)); //正确
    25. end.
  • 预期结果

报主程序名、主程序参数、子过程名不能作为函数实参以及函数实参未定义的错

  • 测试结果
  1. [Invalid reference] Procedure name “test” can’t be referenced
    2. [Expression type error!] Expression “test” used for 1th actual parameter of function call of “fun” should be integer but not error.
    3. [Invalid reference!] “input” is a parameter of program, it can’t be referenced.
    4. [Expression type error!] Expression “input” used for 1th actual parameter of function call of “fun” should be integer but not error.
    5. [Invalid reference!] “pro” is a procedure, it can’t be referenced.
    6. [Expression type error!] Expression “pro” used for 1th actual parameter of function call of “fun” should be integer but not error.
    7. [Undefined identifier!] v has not been defined.
    8. [Expression type error!] Expression “v” used for 1th actual parameter of function call of “fun” should be integer but not error.
  • 分析

函数调用,表达式无法作为实参的情况。测试结果符合预期,语义分析程序继续运行。

1.3.5 测试5

  • 测试用例:函数调用,实参无法被引用调用的情况(不能是常量、不能是复杂表达式,只能是简单变量或数组元素)
  1. program test(input,output);
    2. const h=5;
    3. var d:array[1..5] of integer;
    4. e,f,g:integer;
    5. function fun(var a,b,c:integer):integer;//检查a,b,c是否已经从小到大排序
    6. begin
    7. if a<=b then
    8. if b<=c then
    9. fun:=1;
    10. fun:=0
    11. end;
    12.
    13. procedure pro(var a:integer;b:integer);
    14. var c:integer;
    15. begin
    16. writeln(fun(a,b,c)); //正确
    17. end;
    18. begin
    19. writeln(fun(d[1],d[2],d[3]));//正确
    20. writeln(fun(h,e,f)); //第一个参数是常量标识符,不能作为引用参数对应的形参
    21. writeln(fun(d,e,f)); //第一个参数是数组名,不能作为引用参数对应的形参
    22. writeln(fun(e+f,e,f)); //第一个参数是复杂表达式,不能作为引用参数对应的形参
    23. writeln(fun(e,e>f,f)); //第二个参数是复杂表达式,不能作为引用参数对应的形参
    24. writeln(fun(e,f,1)); //第三个参数是常量,不能作为引用参数对应的形参
    25. end.
  • 预期结果

报函数的实参不能是常量、数组名和复杂表达式的错

  • 测试结果
  1. [Referenced actual parameter error!] The 1th actual parameter expression should be a normal variable、value parameter、referenced parameter or array element.
    2. [Invalid reference!] “d” is a array, it can’t be referenced.
    3. [Referenced actual parameter error!] The 1th actual parameter expression should be a normal variable、value parameter、referenced parameter or array element.
    4. [Referenced actual parameter error!] The 1th actual parameter expression should be a normal variable、value parameter、referenced parameter or array element.
    5. [Referenced actual parameter error!] The 2th actual parameter expression should be a normal variable、value parameter、referenced parameter or array element.
    6. [Referenced actual parameter error!] The 3th actual parameter expression should be a normal variable、value parameter、referenced parameter or array element.
  • 分析

函数调用,实参无法被引用调用的情况(不能是常量、不能是复杂表达式,只能是简单变量或数组元素) 。测试结果符合预期,语义分析程序继续运行。

1.3.6 测试6

  • 测试用例:函数调用,传值参数支持从int到real的隐式类型转化,而引用参数则需类型强一致,即不支持任何类型转换
  1. program test(input,output);
    2. var d,e,f:integer;
    3. function fun(var a:real;b,c:real):integer;//a为引用参数, b和c为传值参数
    4. begin
    5. if a<=b then
    6. if b<=c then
    7. fun:=1;
    8. fun:=0
    9. end;
    10.
    11. begin
    12. writeln(fun(d,e,f)); //d为integer类型,引用参数必须保证类型强一致,所以第一个实参表达式报错
    13. end.
  • 预期结果

报引用参数类型不匹配的错误

  • 测试结果
  1. [Expression type error!] Expression “d” used for 1th actual parameter of function call of “fun” should be real but not integer.
  • 分析

函数调用,传值参数支持从int到real的隐式类型转化,而引用参数则需类型强一致,即不支持任何类型转换

1.3.7 测试7

  • 测试用例:将函数单独作为一条语句
  1. program test(input,output);
    2. var d,e,f:integer;
    3. function fun(var a:real;b,c:real):integer;//a为引用参数, b和c为传值参数
    4. begin
    5. if a<=b then
    6. if b<=c then
    7. fun:=1;
    8. fun:=0
    9. end;
    10.
    11. begin
    12. fun(d,e,f);//该PASCAL-S语言不支持函数的未引用调用
    13. end.
  • 预期结果

报function是一个函数而不是一个过程的错误

  • 测试结果
  1. [Symbol kinds mismatch!] “fun” defined at line 3 is a function but not a procedure.
  • 分析

PASCAL_S不支持函数单独作为一条语句,因此报错。测试结果符合预期,语义分析程序继续运行。