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.
- 预期结果
报函数返回值类型和表达式类型不匹配、赋值语句左右表达式类型不匹配的错误
- 测试结果
- [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
- 测试用例:将非过程作为过程调用,或者过程未定义
- 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.
- 预期结果
报将非过程错当为过程调用和过程未定义的错误
- 测试结果
- [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语句相关检查
- 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.
- 预期结果
报函数返回值类型错误和过程、主程序不需要返回值的错误
- 测试结果
- [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的参数只能是变量或数组元素
- 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函数参数的错误
- 测试结果
- [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在调用时至少得有一个实参
- program test(input,output);
2. begin
3. read;
4. write;
5. end.
- 预期结果
报库函数read、write至少包含一个参数的错误
- 测试结果
- [Read actual parameter missing!]
procedure “read” must have at least one actual parameter.
2. [Write actual parameter missing!]procedure “write“ must have at least one actual parameter.
- 分析
1.2.5 测试5
- 测试用例:writeln可以不带参数
- program test(input,output);
2. begin
3. writeln;
4. end.
- 预期结果
语义分析程序不报错
- 测试结果
语义分析程序没有报错
- 分析
库函数writeln可以没有参数。测试结果符合预期,语义分析程序继续运行。
1.2.6 测试6
- 测试用例:过程调用时实参与形参的对应检查
- 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没有实参、参数个数不够以及参数类型不匹配的错误
- 测试结果
- [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
- 测试用例:过程调用,表达式无法作为实参的情况
- 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没有返回值的警告
- 测试结果
- **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
- 测试用例
- 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.
- 预期结果
报常量、常量标识符、复杂表达式、数组名不能作为引用参数的错误
- 测试结果
- [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
- 测试用例
- 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的错误
- 测试结果
- [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
- 测试用例
- 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参数不能是数组名或者复杂表达式的错误
- 测试结果
- [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测试子程序定义的宏观检查
- 测试用例:子程序名已定义
- 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.
- 预期结果
报过程名已被定义的错误
- 测试结果
- [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
- 测试用例:缺少返回值语句
- 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.
- 预期结果
报子函数缺少返回值语句的警告
- 测试结果
- [Return value statement missing!]
Incomplete return value statement of function “fun”.
- 分析
1.4.2 测试2
- 测试用例
- 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
- 测试用例:缺少返回值语句
- 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.
- 预期结果
报子函数没有返回值的警告
- 测试结果
- [Return value statement missing!]
Incomplete return value statement of function “fun”.
- 分析
1.4.4 测试4
- 测试用例
- 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
- 测试用例
- 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
- 测试用例
- 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.
- 预期结果
语义分析程序不报错
- 测试结果
语义分析程序没有报错
- 分析
测试结果符合预期,语义分析程序继续运行