设计词法分析之基于lex实现词法分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

设计词法分析之基于
l e x实现词法分析 SANY标准化小组 #QS8QHH-HHGX8Q8-GNHHJ8-HHMHGN#
词法分析程序
一、设计目的
通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将其分解成各类单词的词法分析方法。

二、设计要求
要求将用模拟语言书写的源程序进行词法分析,输出源程序清单,Token文件和错
误信息文件,若有错误,必须输出错误在源程序中行号和列号,并将符号表和字符串以文件的形式写出来。

三、设计说明
基于Parser Genarator的词法分析器构造方法。

Lex输入文件由3个部分组成:定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。

这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下{definitions}
%%
{rules}
%%
{auxiliary routines}
而且第一部分用“%{”和“%}”括起来。

第一和第三个部分为C语言的代码和函数定义,第二个部分为一些规则。

正规式定义
定义正则表达式如下
ID = letter letter*
NUM = digit digit*
Letter = a|…|z|A|…|Z
Digit = 0|…|9
Keyword = else|if|int|return|void|while
Special symbol = +|-|*|/|<|<=|>|>=|==|!=|=|;|,|(|)|[|]|{|}|/*|*/
White space = “ ”
Enter = \n
在lex中的构造
letter [A-Za-z]
digit [0-9]
id ({letter}|[_])({letter}|{digit}|[_])*
error_id ({digit})+({letter})+
num {digit}+
whitespace [ \t]+
enter [\n]+
转换规则定义
在Lex中的规则定义构造
定义识别保留字规则
"int"|"else"|"return"|"void"|"if"|"while"
{Upper(yytext,yyleng);
printf("%d 行 ",lineno);
printf("%s reserved word\n",yytext);}//保留字
定义识别数字规则
{num}
{printf("%d 行 ",lineno);
printf("%s NUM\n",yytext);}//数字
定义识别专用符号规则","|";"|"("|")"|"{"|"}"|"*"|"/"|"+"|"-"|">"|"<"|">="|"<="|"=="|"!="|"="|"/*"|"*/" {printf("%d 行 ",lineno);
printf("%s special symbol\n",yytext);}//特殊符号
定义识别标识符规则
{id}
{printf("%d 行 ",lineno);
printf("%s ID\n",yytext);}//标识符
定义识别错误的字符串规则
当开头为数字的后面为字母的字符串时,是错误的标识符。

{error_id}
{printf("error:%s\n",yytext);}//以数字开头的字符自动报错
定义忽略空格规则
{whitespace}
{/* skip whitespace */}//忽略空格
定义忽略回车规则
{enter}
{lineno++;}//遇到回车自动加行号忽略
辅助程序
辅助程序集中包括
主函数main ()和辅助函数toupper()。

程序代码实现
%{
#include <>
#include <>
#include <>
int yywrap();
int lineno=1;
%}
delim [ \t]
ws {delim}+
letter [A-Za-z]
digit [0-9]
id {letter}({letter}|{digit})*
number {digit}+
error_id ({digit})+({letter})+
enter [ \n]
spchar ("{"|"}"|"["|"]"|"("|")"|";"|"="|",")
ariop ("+"|"-"|"*"|"/")
relop ("<"|"<="|">"|">="|"=="|"!=")
comment \/\*(\*[^/]|[^*])*\*\/
reswd (int|else|return|void|if|while)
%%
{ws} {}
{comment} {}
{enter} {lineno++;}
{reswd} {fprintf(yyout,"%d行\tkeywod\t%s\n",lineno,yytext);} {spchar} {fprintf(yyout,"%d行\tspchar\t%s\n",lineno,yytext);} {id} {fprintf(yyout,"%d行\tidentifier\t%s\n",lineno,yytext);}
{number} {fprintf(yyout,"%d行\tnumber\t%s\n",lineno,yytext);}
{error_id} {fprintf(yyout,"%d行\terror_id\t%s\n",lineno,yytext);}
{ariop} {fprintf(yyout,"%d行\tari_op\t%s\n",lineno,yytext);}
{relop} {fprintf(yyout,"%d行\trel_op\t%s\n",lineno,yytext);}
%%
int yywrap() {return 1;}
int main(void)
{
char infilename[100];
printf("输入文件名:");
scanf("%s",infilename);
yyin = fopen(infilename,"r");
yyout = fopen("out","w");
yylex();
return 0;
}
四、运行结果及分析
测试的C语言代码:
测试结果:
测试的C语言代码:
测试结果:
测试代码:
测试结果:
五、总结
通过本次课程设计的练习,学会运用Lex自动构造词法分析器,学会了基于Parser Genarator的词法分析器构造方法。

掌握了词法分析器的原理以及功能。

词法分析是编译过程中的一个阶段,在语法分析前进行。

也可以和语法分析结合在一起作为一遍,由语法分析程序调用词法分析程序来获得当前单词供语法分析使用。

词法分析程序的主要任务:读源程序,产生单词符号。

词法分析程序的其他任务:滤掉空格,跳过注释、换行符追踪换行标志,复制出错源程序,宏展开,等等等等。

词法分析工作从语法分析工作独立出来的原因:简化设计,改进编译效率,增加编译系统的可移植性。

而且从划分关键字,运算符,界符,标识符和常量,才发现数字,字母及符号组合有很多很多,无法全部枚举,所以在新建的文本文档中只象征性的列出几种符号,但这并不影响
此法分析结果的完成。

总之,通过本次实验,一点点分析词法分析器的功能,并努力实现它,掌握了课程设计内容的同时也锻炼了自己分析解决问题的能力以及编程能力,收获颇丰!。

相关文档
最新文档