词法分析之基于Lex实现词法分析

Renaissance

发布日期: 2018-11-05 09:50:50 浏览量: 243
评分:
star star star star star star star star star_border star_border
*转载请注明来自write-bug.com

一、设计目的

通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将其分解成各类单词的词法分析方法。

二、设计要求

编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。 并依次输出各个单词的内部编码及单词符号自身值。

(遇到错误时可显示“Error”,然后跳过错误部分继续显示)

三、设计说明

3.1 需求分析

3.1.1 输入及其范围

Lex输入文件由3个部分组成:定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下:

  1. {definitions}
  2. %%
  3. {rules}
  4. %%
  5. {auxiliary routines}

范围

  • 识别保留字:const,var,begin,end,read,while,call,writeln等保留字类别码为1

  • 运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;类别码为2

  • 界符包括:,、;、{、}、(、); 类别码为3

  • 常数为无符号整形数;单词类别码为4

  • 其他的都识别为标识符;单词类别码为5

  • 错误字符类别码为 6

3.1.2 输出形式

([数字],“单词“)数字代表所识别的单词所属的类型。

3.1.3 程序功能

读取文件中的源程序,然后对源程序分析,输出分析结果。

3.1.4 测试数据

将测试数据写在文本文件中,测试为程序的输入数据。

3.2 概要设计

3.2.1 数据类型的定义

  1. %{
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int count = 0;
  5. %}
  6. delim [" "\n\t]
  7. whitespace {delim}+
  8. operator \+|-|\*|\/|:=|#|=
  9. //operator \+|-|\*|\/|:=|>=|<=|#|=
  10. reservedWord [cC][oO][nN][sS][tT]|[vV][aA][rR]|[pP][rR][oO][cC][eE][dD][uU][rR][eE]|[bB][eE][gG][iI][nN]|[eE][nN][dD]|[iI][fF]|[tT][hH][eE][nN]|[wW][hH][iI][lL][eE]|[dD][oO]|[rR][eE][aA][dD]|[cC][aA][lL][lL]|[wW][rR][iI][tT][eE]|[wW][rR][iI][tT][eE][lL][nN]
  11. delimiter [,\.;]
  12. constant ([0-9])+
  13. identfier [A-Za-z]([A-Za-z][0-9])*
  14. %%

3.2.2 主程序流程

3.2.3 模块间的调用关系

3.3 详细设计

3.3.1 主体代码部分

  1. %%
  2. {reservedWord} {count++;printf("%d\t(1,‘%s’)\n",count,yytext);}
  3. {operator} {count++;printf("%d\t(2,‘%s’)\n",count,yytext);}
  4. {delimiter} {count++;printf("%d\t(3,‘%s’)\n",count,yytext);}
  5. {constant} {count++;printf("%d\t(4,‘%s’)\n",count,yytext);}
  6. {identfier} {count++;printf("%d\t(5,‘%s’)\n",count,yytext);}
  7. {whitespace} { /* do nothing*/ }
  8. %%
  9. void main()
  10. {
  11. printf("词法分析器输出类型说明:\n");
  12. printf("1:保留字\n");
  13. printf("2:运算符\n");
  14. printf("3:分界符\n");
  15. printf("4:常 数\n");
  16. printf("5:标识符\n");
  17. printf("\n");
  18. yyin=fopen("example.txt","r");
  19. yylex(); /* start the analysis*/
  20. fclose(yyin);
  21. system("PAUSE");/*暂停停, 使DOS窗口停住*/
  22. }
  23. int yywrap()
  24. {
  25. return 1;
  26. }

四、运行结果及分析

4.1 测试数据

在example.txt文件中写入如下数据。

  1. const a=10;
  2. var b,c;
  3. procedure p;
  4. begin
  5. c:=b+a;
  6. end;
  7. begin
  8. read(b);
  9. while b#0 do
  10. begin
  11. call p;
  12. writeln(2*c);
  13. read(b);
  14. end
  15. end.

4.2 测试输出的结果

4.3. 设计与思考

基于lex的词法分析,一个模块定义好了之后,其他模块也就出来了。难点在于正则表达式的设计,每个模块都有定义集,规则集和辅助程序集。而且第一部分用“%{”和“%}”括起来。第一和第三个部分为C语言的代码和函数定义,第二个部分为一些规则。

五、总结

通过本次实验,学会了基于Lex的词法分析器构造方法。在实验过程中,万事开头难,刚开始不知道怎么做,以及不知道如何使用老师给的软件,在仔细分析了需求之后,查找了一些关于Parser Genarator 2软件的使用方法,但是在使用过程中错误地使用.y后缀名导致Lex编译总是出错,后来看教程带着尝试的心理改成了.l后缀名才终于成功让Lex程序跑起来,正确生成编译器C代码。

有了编译器C代码之后打算开始用Code Block编译,但是发现其中的yyleh.h类库找不到,后来用VS2015也一直出现问题,是在没办法,只好按照老师给的VC++的教程安装VC++6.0并导入yylex.h类库,最终获得了成功,很是欣喜。

上传的附件 cloud_download 词法分析之基于Lex实现词法分析.7z ( 858.22kb, 11次下载 )
error_outline 下载需要6点积分

发送私信

聪明但不自以为是,有趣但不哗众取宠,黑暗但不深不见底

8
文章数
11
评论数
最近文章
eject