编译原理课程设计报告-C语言词法分析器参考
编译原理
课程设计报告
题目名称C语言词法分析器班 级学 号 姓 名指导教师 编写时间2010/12/10
目 录
1.课程设计题目名称- 2 -
2.课程设计目的与任务- 2 -
3.设计思想和实现方法- 3 -
4.程序说明- 3 -
5.程序运行结果和测试报告- 4 -
6.存在问题及分析- 6 -
7.总结及体会- 6 -
参考文献- 6 -
附件一- 7 -
附件二- 11 -
课程设计题目名称
使用工具实现C/C++语言词法分析器
课程设计目的与任务
人数:1人
时间:一周
输入:C/C++源代码文件,即后缀为c/cpp的文件。
输出:后缀为tok的文本性文件。
实现功能:完成C/C++语言的词法分析器
(C语言词法记号及其含义详见附件一)
词法记号含义LB“{”LP“(”RB“}”RP“)”PLUS“+”……
设计思想和实现方法
词法分析器的作用如下:
读入源程序字符序列对源程序进行预处理,如删除注释和回车换行符,宏展开等识别源程序中的单词符号,创建符号表并在相应的符号表中登录信息%{
#include "stdio.h"
int linenum;
%}
第二段:规则部分
规则部分起始于“?%%”符号,终止于“%%”符号,其间则是词法规则。词法规则由模式和动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分由C语言语句组成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex将识别出来的单词存放在yytext[]字符数据中,因此该数组的内容就代表了所识别出来的单词的内容。
例如:
%%
delim [ \t\n]
ws {delim}+
number {digit}+(\.{digit}+)?(E[+\-]?{digit}+)?
{ws} {/*忽略空格符、制表符、换行符的操作*/}
{number} {fprintf(yyout,"%s\t//Number(常数)\n",yytext);}
%%
在上述代码中,“ws {delim}+”代表识别空格符、制表符、换行符的规则,“{ws} {/*忽略空格符、制表符、换行符的操作*/}”就代表对识别出的“ws”进行操作,即忽略空格符、制表符、换行符。
第三段:是补充的用户自定义函数。
例如:
int yywrap() {return 1;}
int main(int argc, char *argv[])
{
yyin = fopen("input.c","r");
yyout = fopen("output.tok","w");
printf("input.c文件分析完毕,结果保存在output.tok文件\n");
fprintf(yyout,"//c语言词法分析\n//\n//杨凯\n//2010/12/10\n\n//词法分析如下:\n");
yylex();
return 0;
}
上述代码就是一个用户自定义的函数,此函数实现的功能是:打开input.c文件进行词法分析,并将结果输出到output.tok文件中。
程序运行结果和测试报告
使用Lex编程,命名为mylexer.l,使用Parser Generator 2编译生成mylexer.c、mylexer.h和mylexer.v文件,在Microsoft visual c++6.0中新建一个工程,命名为test,将mylexer.c加入到source files,将mylexer.h加入到header files,配置好环境变量后编译运行,运行结果如下图所示。用来测试的C语言文件名为input.c,经词法分析后输出的文件命名为output.tok。
由结果可知,顺利完成词法分析任务。
图1 编译运行运行结果
图2 input.c文件截图
图3 output.tok文件截图
存在问题及分析
词法分析的正则表达式编写有些不是很全面,比如说识别常数“number”的正则表达式就无法识别8进制、16进制数据。
识别某些词法记号的正则表达式编写的不是很严谨,比如说在识别C语言预处理定义语句的正则表达式仅仅只能识别出预处理语句,而无法进行预处理包含的头文件的词法分析。
用户自定义程序编写的较为简陋,若能美化一下,人机交互将会更美好。
对Lex编程还不是很了解,对词法分析器的作用以及工作原理的理解还有待提高。
总结及体会
在拿到本次课程设计题目后,对完成此次课程设计的两种主流方案进行了一些思考,用C++语言直接编写词法分