1.1测试环境
1.1.1 依赖
词法分析单元测试本质上不依赖于其它任何模块,但需要对源程序进行预处理,即在源程序的一开始添加一个换行,并把所有的字母转化为小写,该工作在main.cpp中进行。
词法分析的记号返回值需要用宏进行定义,也可以用YACC编写一个简单的YACC源程序生成yy.tab.cpp和yy.tab.h,里面包含了记号的宏定义。我们采用了后者。所编写的简单YACC程序如下,主要是对记号进行了声明。
%{#include "main.h"#include "yacc.tab.h"extern "C" {void yyerror(const char *s);int yyparse();extern int yylex();}%}%token PROGRAM%token CONST%token VAR%token ARRAY%token OF%token PROCEDURE%token FUNCTION%token _BEGIN%token END%token IF%token THEN%token FOR%token TO%token DO%token ELSE%token REPEAT%token UNTIL%token WHILE%token IDENTIFIER%token UINUM%token UFNUM%token CHAR%token TYPE%token ASSIGNOP%token RELOP%token ADDOP%token MULOP%token NOT%token RANGEDOT%start programstruct%locations%%programstruct:%%void yyerror(const char *s) {cout << s << endl;}
1.1.2 调试输出
如果定义了宏LEXDEBUG,那么就可以输出词法分析程序的调试输出,即输出按顺序输出每一个记号及其属性。具体做法是,在每一个正则表达式的动作中添加如下代码(以标识符为例)
#ifdef LEXDEBUGcout << "identifier: " << yylval->str << endl;#endif
那么只要在一开始定义宏LEXDEBUG,就可以产生调试输出
另外,一旦遇到词法错误,也会输出词法错误的详细信息。
1.1.3 获取可执行文件
采用如下命令
flex lex.l //编译lex.l,生成lex.yy.c
ren lex.yy.c lex.yy.cpp //将lex.yy.c更名为lex.yy.cpp
bison -vd --debug yacc.y //编译yacc.y,生成yacc.tab.h和yacc.tab.c
ren yacc.tab.c yacc.tab.cpp //将yacc.tab.c更名为yacc.cpp
g++ lex.yy.cpp yacc.tab.cpp main.cpp -o pascal2c.exe
//编译生成可执行文件pascal2c.exe
1.1.4 输入文件
1.1.5 输出文件
1.2测试计划
- 有针对性的测试每一种词法错误
- 组合上述词法错误,词法分析程序能否成功处理错误并恢复(有一些词法错误,例如行长度超过限制,会导致词法分析程序直接停止运行)
- 以一个较复杂的,没有错误的程序作为最终测试
