词法分析器实验报告

更新时间:2023-09-25 22:09:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

词法分析器实验报告

姓名: 实验内容:

用flex工具生成一个PL/0语言的词法分析程序,对PL/0语言的源程序进行扫描,识别出单词符号的类别,统计输出各种符号的信息

学号: 时间:

实验目的:

a) b) c) d)

理解编译器的工作机制 掌握编译器的构造方法

掌握词法分析器的生成工具LEX的用法 掌握语法分析器的生成工具YACC的用法

实验环境: Window XP Visual C++ 6.0 Flex.exe 实验要求:

1.实现预处理功能。

源程序中可能包含有对程序执行无意义的符号,要求将其剔除。

2.实现词法分析功能。

输入:预处理过的源程序。

输出:把单词符号分为下面五类,然后统计PL0源程序中各单词符号出现的次数。

1) K类(关键字) 2) I类(标识符) 3) C类(常量)

4) P类(算符及界符) 5) O类(其他)

3.规则

? 语句类型:

– 赋值语句,if...then..., while...do..., read, write, call, 复合语句begin... end,

说明语句: const..., var..., procedure…

? 13个关键字:

– if, then, while, do, read, write, call, begin, end, const, var, procedure, odd

? 标识符定义为identifier,在程序中由范式定义: – identifier {letter}({letter}|{digit})*

? 常量定义为Constant,在程序中由范式定义:

– number {digit}+

? 界符作为boundary-operator,在程序中通过列举定义:

– \

? 算符作为Operator,在程序中通过列举定义:

– \

? 关系符号作为arithmetic-operator,在程序中通过列举定义 – \

? 此外在程序中实现了错误字符,以及未知字符的定义:

– wrongid ({digit}+){letter}({letter}|{digit})*

? 空格、回车、换行符跳过。

代码调试:

根据lex的源程序的语法规则,源程序分为4个部分。

声明:

%{

#include #include #define maxname 20 #define maxnum 1000

void print(); //输出token序列; void main(int argc,char*argv[]); //主函数;

struct token{ //二元组; char*idproperty; //token属性值; char*idname; //识别的token名字;

}entity[maxnum]; //定义1000个这样的token,大小可改变;

char filename[maxname]; //源程序文件名; int errnum=0; //错误token的数目; int value; //属性值int型; int linenum=1; //行数;

int count=0; //token的个数; FILE*fpin; //测试文件指针; FILE*fpout; //结果文件指针; %}

辅助定义:

digit [0-9] letter [a-zA-Z] number {digit}+

identifier {letter}({letter}|{digit})*

wrongid ({digit}+){letter}({letter}|{digit})* newline [\\n] whitespace [\\t]+

识别规则:

\ {value=0;print();}

{identifier} {value=1;print();} {number} {value=2;print();}

\ {value=3;print();}

\ {value=4;print();} \ {value=5;print();} {wrongid} {value=6;print();} {newline} {linenum+=1;} {whitespace} {;} \ {;}

. {value=7;print();} %%

用户子程序:

void print() {

count++;

if((fpout=fopen(\ printf(\ exit(0); }

if(value<=5){ //正常情况下处理方式 switch(value){

case 0:entity[count-1].idproperty=\ case 1:entity[count-1].idproperty=\ case 2:entity[count-1].idproperty=\

case 3:entity[count-1].idproperty=\ case 4:entity[count-1].idproperty=\ case 5:entity[count-1].idproperty=\ }

entity[count-1].idname=yytext; fprintf(fpout,\<符号: \\\, 类\\n\

}else{ //wrongid时处理方式

型:%s >

errnum+=1; switch(value){

case 6:entity[count-1].idproperty=\ case 7:entity[count-1].idproperty=\ }

entity[count-1].idname=yytext; fprintf(fpout,\[line:%d]: \\\%s \\n\ }

fclose(fpout); }

void main() {

printf(\ scanf(\

if((fpin=fopen(filename,\//打开文件 printf(\ exit(0); }

yyin=fpin;

yylex(); /* yyin是个FILE类型的指针, 指向词法分析器要接收的待分析程序的指针。每调用一次,yylex 的返回值为当前分析的Word类型值。当文件结束时,yylex 的返回值为0。*/

if((fpout=fopen(\ printf(\ exit(0); }

fprintf(fpout,\

fprintf(fpout,\

fprintf(fpout,\===========\\n\ fclose(fpout);

yywrap(); }

操作过程:

Windows下用felx进行编译:

生成文件:

VC中编译:

生成文件记录结果My.txt:

测试结果如下(局部截图):

添加错误代码于第二行:

然后得到测试结果为:

本文来源:https://www.bwwdw.com/article/w0ld.html

Top