1.1赋值语句相关类型检查(包括以赋值语句形式给出的函数返回值语句)

  • 测试用例
  1. program test(input,output);
    2. var a:integer;
    3. b:real;
    4. c:boolean;
    5. d:char;
    6. function fib(i:integer):integer;
    7. begin
    8. if i=0 then
    9. fib:=’a’ //表达式类型为char,但是返回值类型为integer
    10. else
    11. begin
    12. if i=1 then
    13. fib:=1 //正确
    14. else
    15. fib:=fib(i-1)+fib(i-2); //正确
    16. end;
    17. end;
    18. begin
    19. a:=a2; //正确
    20. a:=b; //左值类型为integer,右值类型为real,错误
    21. b:=a; //左值类型为real, 右值类型为integer,正确
    22. a:=a+b; //左值类型为integer,右值类型为real,错误
    23. b:=a+b; //左值类型为real,右值类型为integer,正确
    24. a:=c; //左值类型为integer,右值类型为boolean,错误
    25. c:=a; //左值类型为boolean,右值类型为integer,错误
    26. a:=d; //左值类型为integer,右值类型为char,错误
    27. d:=a; //左值类型为char,右值类型为integer,错误
    28. b:=c; //左值类型为real,右值类型为boolean,错误
    29. c:=b; //左值类型为boolean,右值类型为real,错误
    30. b:=d; //左值类型为real,右值类型为char,错误
    31. d:=b; //左值类型为char,右值类型为real,错误
    32. c:=d; //左值类型为boolean,右值类型为char,错误
    33. d:=c; //左值类型为char,右值类型为boolean,错误
    34. *end
    .
  • 预期结果

报函数返回值类型和表达式类型不匹配、赋值语句左右表达式类型不匹配的错误

  • 测试结果
  1. [Return type of funciton mismatch!] The type of return expression is char ,but not integer as function “fib” defined.
    2. [Assign statement type mismatch!] Left “a” type is integer while right “b” type is real.
    3. [Assign statement type mismatch!] Left “a” type is integer while right “a + b” type is real.
    4. [Assign statement type mismatch!] Left “a” type is integer while right “c” type is boolean.
    5. [Assign statement type mismatch!] Left “c” type is boolean while right “a” type is integer.
    6. [Assign statement type mismatch!] Left “a” type is integer while right “d” type is char.
    7. [Assign statement type mismatch!] Left “d” type is char while right “a” type is integer.
    8. [Assign statement type mismatch!] Left “b” type is real while right “c” type is boolean.
    9. [Assign statement type mismatch!] Left “c” type is boolean while right “b” type is real.
    10. [Assign statement type mismatch!] Left “b” type is real while right “d” type is char.
    11. [Assign statement type mismatch!] Left “d” type is char while right “b” type is real.
    12. [Assign statement type mismatch!] Left “c” type is boolean while right “d” type is char.
    13. [Assign statement type mismatch!] Left “d” type is char while right “c” type is boolean.
  • 分析

real类型不能隐式转换为integer,而integer可以隐式转换为real;integer、real和bool类型不存在隐式转换。测试结果符合预期,语义分析程序继续运行

1.2测试过程调用相关语义检查

1.2.1 测试1

  • 测试用例:将非过程作为过程调用,或者过程未定义
  1. program test(input,output);
    2. var a,b:integer;
    3. c:char;
    4. f:array[1..5] of integer;
    5. function fun:integer;
    6. begin
    7. fun:=1;
    8. end;
    9. procedure pro2(var d:real; e:boolean);
    10. begin
    11. d; //错把引用参数当成函数调用
    12. e; //错把传值参数当成函数调用
    13. pro2(d,e); //正确
    14. end;
    15. begin
    16. pro; //过程未定义
    17. pro2(a, a>b); //正确
    18. test; //将主程序名错当为过程调用
    19. input; //将主程序参数错当为过程调用
    20. a; //将integer变量错当成过程调用
    21. c; //将char变量错当成过程调用
    22. fun; //将函数错当成过程调用
    23. f; //将数组错当成过程调用
    24. end.
  • 预期结果

报将非过程错当为过程调用和过程未定义的错误

  • 测试结果
  1. [Symbol kinds mismatch!] “d” defined at line 9 is a var parameter but not a procedure.
    2. [Symbol kinds mismatch!] “e” defined at line 9 is a value parameter but not a procedure.
    3. [Undefined identifier!] pro has not been defined.
    4. [Expression type error!] Expression “a” used for 1th actual parameter of procedure call of “pro2” should be real but not integer.
    5. [Symbol kinds mismatch!] “test” defined at line 1 is a (sub)program name but not a procedure.
    6. [Symbol kinds mismatch!] “input” defined at line 1 is a parameter of program but not a procedure.
    7. [Symbol kinds mismatch!] “a” defined at line 2 is a normal variant but not a procedure.
    8. [Symbol kinds mismatch!] “c” defined at line 3 is a normal variant but not a procedure.
    9. [Symbol kinds mismatch!] “fun” defined at line 5 is a function but not a procedure.
    10. [Symbol kinds mismatch!] “f” defined at line 4 is a array but not a procedure.
  • 分析

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

1.2.2 测试2

  • 测试用例:exit语句相关检查
  1. program test(input,output);
    2. var a,b:integer;
    3. c:char;
    4. e:real;
    5. f:array[1..5] of integer;
    6. function fun:real;
    7. begin
    8. exit(f[1]); //正确,integer到real的隐式类型转换
    9. exit(a); //正确,integer到real的隐式类型转换
    10. exit(c); //错误,定义的返回值类型为real,而返回值表达式的类型为char
    11. exit(e); //正确,返回值类型一直
    12. exit; //错误,缺少返回值表达式
    13. exit(a,b); //错误,返回值表达式多余
    14. end;
    15. procedure pro;
    16. begin
    17. exit(1); //错误,返回值表达式多余
    18. exit; //正确,过程不需要返回值
    19. end;
    20. begin
    21. exit(1); //错误
    22. exit; //正确,主程序不需要返回值
    23. end.
  • 预期结果

报函数返回值类型错误和过程、主程序不需要返回值的错误

  • 测试结果
  1. [Return type of funciton mismatch!] The type of return expression is char ,but not real as function “fun” defined.
    2. [Return value missing!] Number of return value of function must be 1, that is, exit must have 1 actual parameters.
    3. [Return value redundancy!] Number of return value of function must be 1, that is, exit must have 1 actual parameters.
    4. [Return value redundancy!] Number of return value of procedure must be 0, that is, exit must have no actual parameters.
    5. [Return value redundancy!] Number of return value of procedure must be 0, that is, exit must have no actual parameters.
  • 分析

exit语句是PASCAL_S支持的库函数之一,用于返回函数的返回值,返回的表达式类型错误、多余、缺少等都会报错。测试结果符合预期,语义分析程序继续运行

1.2.3 测试3

  • 测试用例:read语句相关检查 read的参数只能是变量或数组元素
  1. program test(input,output);
    2. var a,b:integer;
    3. c:char;
    4. e:real;
    5. f:array[1..5] of integer;
    6. function fun:integer;
    7. begin
    8. fun:=1;
    9. end;
    10. procedure pro(var d:integer;h:char);
    11. var i:real;
    12. j:boolean;
    13. begin
    14. read(d,h,i,j); //正确
    15. read(a,c,e,f[1]); //正确
    16. read(f); //错误,数组名不能作为read的参数
    17. read(test); //错误,主程序名不能作为read的参数
    18. read(input); //错误,主程序参数不能作为read的参数
    19. read(pro); //错误,过程名不能作为read的参数
    20. read(fun); //错误,函数名不能作为read的参数
    21. end;
    22. begin
    23. read(pro); //错误,过程名不能作为read的参数
    24. read(fun); //错误,函数名不能作为read的参数
    25. read(f); //错误,数组名不能作为read的参数
    26. read(a,b,c,e,f[1]); //正确
    27. end.

  • 预期结果

报非变量、非数组元素不能作为read函数参数的错误

  • 测试结果
  1. [Read boolean error!] The 4th actual parameter of read “j” is boolean, it can’t be read.
    2. [Invalid reference!] “f” is a array, it can’t be referenced.
    3. [Actual parameter of read procedure type error!] “read” 1th expression parameter “f” is not a variant or an array element.
    4. [Invalid reference] Procedure name “test” can’t be referenced
    5. [Actual parameter of read procedure type error!] “read” 1th expression parameter “test” is not a variant or an array element.
    6. [Invalid reference!] “input” is a parameter of program, it can’t be referenced.
    7. [Actual parameter of read procedure type error!] “read” 1th expression parameter “input” is not a variant or an array element.
    8. [Invalid reference] Procedure name “pro” can’t be referenced
    9. [Actual parameter of read procedure type error!] “read” 1th expression parameter “pro” is not a variant or an array element.
    10. [Actual parameter of read procedure type error!] “read” 1th expression parameter “fun” is not a variant or an array element.
    11. [Invalid reference!] “pro” is a procedure, it can’t be referenced.
    12. [Actual parameter of read procedure type error!] “read” 1th expression parameter “pro” is not a variant or an array element.
    13. [Actual parameter of read procedure type error!] “read” 1th expression parameter “fun” is not a variant or an array element.
    14. [Invalid reference!] “f” is a array, it can’t be referenced.
    15. [Actual parameter of read procedure type error!] “read” 1th expression parameter “f” is not a variant or an array element.
    l 分析
    read库函数的参数只能是var或者数组的元素,不能是主程序名、过程名、参数等。测试结果符合预期,语义分析程序继续运行

    1.2.4 测试4

  • 测试用例:read和write在调用时至少得有一个实参
  1. program test(input,output);
    2. begin
    3. read;
    4. write;
    5. end.
  • 预期结果

报库函数read、write至少包含一个参数的错误

  • 测试结果
  1. [Read actual parameter missing!] procedure “read” must have at least one actual parameter.
    2. [Write actual parameter missing!] procedurewrite“ must have at least one actual parameter.
  • 分析

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

1.2.5 测试5

  • 测试用例:writeln可以不带参数
  1. program test(input,output);
    2. begin
    3. writeln;
    4. end.
  • 预期结果

语义分析程序不报错

  • 测试结果

语义分析程序没有报错

  • 分析

库函数writeln可以没有参数。测试结果符合预期,语义分析程序继续运行。

1.2.6 测试6

  • 测试用例:过程调用时实参与形参的对应检查
  1. program test(input,output);
    2. var a,b:integer;
    3. procedure pro(var c:integer;d:char);
    4. begin
    5. writeln(c);
    6. writeln(d);
    7. end;
    8. begin
    9. pro; //缺少实参
    10. pro(a); //缺少实参
    11. pro(a,’y’); //正确
    12. pro(a,b); //第二个实参类型不匹配
    13. end.
  • 预期结果

报过程pro没有实参、参数个数不够以及参数类型不匹配的错误

  • 测试结果
  1. [Procedure parameter number mismatch!] Procedure “pro” should have 2 but not 0 parameters.
    2. [Procedure parameter number mismatch!] Procedure “pro” should have 2 but not 1 parameters.
    3. [Expression type error!] Expression “b” used for 2th actual parameter of procedure call of “pro” should be char but not integer.
  • 分析

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

1.2.7 测试7

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

报过程名、主程序参数无法作为过程的实参以及过程实参类型不正确、参数未定义的错误;报function没有返回值的警告

  • 测试结果
  1. **Here are the semantic warnings**
    2. [Return value statement missing!] Incomplete return value statement of function “fun”.
    3. **Please pay attention to these semantic warnings**
    4. **Here are the semantic errors**
    5. [Invalid reference] Procedure name “test” can’t be referenced
    6. [Expression type error!] Expression “test” used for 1th actual parameter of procedure call of “pro” should be integer but not error.
    7. [Invalid reference!] “input” is a parameter of program, it can’t be referenced.
    8. [Expression type error!] Expression “input” used for 1th actual parameter of procedure call of “pro” should be integer but not error.
    9. [Undefined identifier!] v has not been defined.
    10. [Expression type error!] Expression “v” used for 1th actual parameter of procedure call of “pro” should be integer but not error.
  • 分析

过程名、未定义的变量不能作为过程的实参。测试结果符合预期,语义分析程序继续运行

1.2.8 测试8

  • 测试用例
  1. program test(input,output);
    2. const h=5;
    3. var d:array[1..5] of integer;
    4. e,f,g:integer;
    5.
    6. procedure pro(var a,b,c:integer);//检查a,b,c是否已经从小到大排序
    7. begin
    8. if a<=b then
    9. if b<=c then
    10. writeln(1)
    11. else
    12. writeln(0)
    13. else
    14. writeln(0);
    15. end;
    16.
    17. begin
    18. pro(d[1],d[2],d[3]); //正确
    19. pro(h,e,f); //第一个参数是常量标识符,不能作为引用参数对应的形参
    20. pro(d,e,f); //第一个参数是数组名,不能作为引用参数对应的形参
    21. pro(e+f,e,f); //第一个参数是复杂表达式,不能作为引用参数对应的形参
    22. pro(e,e>f,f); //第二个参数是复杂表达式,不能作为引用参数对应的形参
    23. pro(e,f,1); //第三个参数是常量,不能作为引用参数对应的形参
    24. 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.2.9 测试9

  • 测试用例
  1. program test(input,output);
    2. var d,e,f:integer;
    3. procedure pro(var a:real;b,c:real);//a为引用参数, b和c为传值参数
    4. begin
    5. if a<=b then
    6. if b<=c then
    7. writeln(1)
    8. else
    9. writeln(0)
    10. else
    11. writeln(0);
    12. end;
    13.
    14. begin
    15. pro(d,e,f); //d为integer类型,引用参数必须保证类型强一致,所以第一个实参表达式报错
    16. end.
  • 预期结果

报引用参数的实参应为real而不是integer的错误

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

过程调用,传值参数支持从int到real的隐式类型转化,而引用参数则需类型强一致,即不支持任何类型转换。测试结果符合预期,语义分析程序继续运行

1.2.10 测试10

  • 测试用例
  1. program test(input,output);
    2. var
    3. a: integer;
    4. b: array [1..5] of integer;
    5. c: integer;
    6. begin
    7. read(a);
    8. read(b);
    9. read(b[1]);
    10. read(a+c);
    11. end.
  • 预期结果

报read参数不能是数组名或者复杂表达式的错误

  • 测试结果
  1. [Invalid reference!] “b” is a array, it can’t be referenced.
    2. [Actual parameter of read procedure type error!] “read” 1th expression parameter “b” is not a variant or an array element.
    3. [Actual parameter of read procedure type error!] “read” 1th expression parameter “a + c” is not a variant or an array element.
  • 分析

read或readln的参数不为简单变量或数组元素。测试结果符合预期,语义分析程序继续运行

1.3测试子程序定义的宏观检查

  • 测试用例:子程序名已定义
  1. program test(input,output);
    2. var a:integer;
    3. b:array[1..5] of integer;
    4. function fun:integer;
    5. begin
    6.
    7. end;
    8.
    9. procedure pro;
    10. begin
    11.
    12. end;
    13.
    14. function fun:char; //已被定义为函数
    15. begin
    16.
    17. end;
    18.
    19. procedure pro; //已被定义为过程
    20. begin
    21.
    22. end;
    23.
    24. procedure test; //已被定义为主程序名
    25. begin
    26.
    27. end;
    28.
    29. procedure input; //已被定义为主程序参数
    30. begin
    31.
    32. end;
    33.
    34. procedure a; //已被定义为变量
    35. begin
    36.
    37. end;
    38.
    39. procedure b; //已被定义为数组
    40. begin
    41.
    42. end;
    43.
    44. begin
    45.
    46. end.
  • 预期结果

报过程名已被定义的错误

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

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

1.4测试函数返回值语句存在性检查

1.4.1 测试1

  • 测试用例:缺少返回值语句
  1. program test(input,output);
    2. function fun:integer;
    3. var a,b:integer;
    4. begin
    5. if a>0 then
    6. fun:=1
    7. else
    8. writeln(a); //该分支缺少返回值语句
    9. end;
    10. begin
    11. writeln(fun);
    12. end.
  • 预期结果

报子函数缺少返回值语句的警告

  • 测试结果
  1. [Return value statement missing!] Incomplete return value statement of function “fun”.
  • 分析

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

1.4.2 测试2

  • 测试用例
  1. program test(input,output);
    2. function fun:integer;
    3. var a,b:integer;
    4. begin
    5. if a>0 then
    6. fun:=1
    7. else
    8. begin
    9. writeln(a);
    10. fun:=3;
    11. end
    12. end;
    13. begin
    14. writeln(fun);
    15. end.
  • 预期结果

语义分析程序不报错

  • 测试结果

语义分析程序没有报错

  • 分析

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

1.4.3 测试3

  • 测试用例:缺少返回值语句
  1. program test(input,output);
    2. function fun(a:integer):integer;
    3. begin
    4. if a=1 then
    5. begin
    6. writeln(‘a’,’=’,’1’);
    7. fun:=1
    8. end
    9. else
    10. begin
    11. if a=2 then
    12. begin
    13. writeln(‘a’,’=’,’2’);//该分支缺少返回值语句
    14. end
    15. else
    16. begin
    17. writeln(‘a’,’=’,’?’);
    18. fun:=3
    19. end;
    20. end;
    21. end;
    22. begin
    23. writeln(fun(5));
    24. end.
  • 预期结果

报子函数没有返回值的警告

  • 测试结果
  1. [Return value statement missing!] Incomplete return value statement of function “fun”.
  • 分析

缺少返回值语句,测试结果符合预期,语义分析程序继续运行

1.4.4 测试4

  • 测试用例
  1. program test(input,output);
    2. function fun(a:integer):integer;
    3. begin
    4. if a=1 then
    5. begin
    6. writeln(‘a’,’=’,’1’);
    7. fun:=1
    8. end
    9. else
    10. begin
    11. if a=2 then
    12. begin
    13. writeln(‘a’,’=’,’2’);
    14. fun:=2
    15. end
    16. else
    17. begin
    18. writeln(‘a’,’=’,’?’);
    19. end;
    20. fun:=100;
    21. end;
    22. end;
    23. begin
    24. writeln(fun(5));
    25. end.
  • 预期结果

语义分析程序不报错

  • 测试结果

语义分析程序没有报错

  • 分析

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

1.4.5 测试5

  • 测试用例
  1. program test(input,output);
    2. function fun(a:integer):integer;
    3. begin
    4. fun:=100; //这里直接返回
    5. if a=1 then
    6. begin
    7. writeln(‘a’,’=’,’1’);
    8. fun:=1
    9. end
    10. else
    11. begin
    12. if a=2 then
    13. begin
    14. writeln(‘a’,’=’,’2’);
    15. fun:=2
    16. end
    17. else
    18. begin
    19. writeln(‘a’,’=’,’?’);
    20. end;
    21. end;
    22. end;
    23. begin
    24. writeln(fun(5));
    25. end.
  • 预期结果

语义分析程序不报错

  • 测试结果

语义分析程序没有报错

  • 分析

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

1.4.6 测试6

  • 测试用例
  1. program test(input,output);
    2. function fun(a:integer):integer;
    3. begin
    4. if a=1 then //该if-else语句所有分支均包含返回值语句
    5. begin
    6. writeln(‘a’,’=’,’1’);
    7. fun:=1
    8. end
    9. else
    10. begin
    11. if a=2 then
    12. begin
    13. writeln(‘a’,’=’,’2’);
    14. fun:=2
    15. end
    16. else
    17. begin
    18. writeln(‘a’,’=’,’?’);
    19. fun:=100;
    20. end;
    21. end;
    22. if a=3 then
    23. writeln(‘a’,’=’,’3’)
    24. else
    25. writeln(‘a’,’=’,’?’,’?’,’?’);
    26. end;
    27. begin
    28. writeln(fun(5));
    29. end.
  • 预期结果

语义分析程序不报错

  • 测试结果

语义分析程序没有报错

  • 分析

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