编译实验词法分析.docx
- 文档编号:5514821
- 上传时间:2022-12-18
- 格式:DOCX
- 页数:15
- 大小:175.40KB
编译实验词法分析.docx
《编译实验词法分析.docx》由会员分享,可在线阅读,更多相关《编译实验词法分析.docx(15页珍藏版)》请在冰豆网上搜索。
编译实验词法分析
词法分析器实验报告
院系:
专业:
小组成员:
学号:
日期:
一、实验的目的与任务
词法分析的目的是将输入的源程序进行划分,给出基本符号(token)的序列,并掠过注解和空格等分隔符号。
基本符号是与输入的语言定义的词法所规定的终结符。
本实验要求学生编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续进行)。
二、实验所要识别的单词分类
1.关键字。
*key[53]={"auto","bool","break","case","catch","char","class","const","continue","default","delete","do","double","else","enum","extern","false","float","for","friend","goto","if","inline","int","long","namespace","new","operator","private","protected","public","register","return","short","signed","sizeof","static","struct","switch","template","this","throw","true","try","typedef","typename","union","unsigned","using","virtual","void","volatile","while"};
2.标识符。
符合文法标识符,由字符和数字组成,首字符必须为下划线或字母。
(hjw,wyp2319,_zhg…..)
3.数字。
整型,浮点型,科学计数。
4.运算符。
*arithmetic[6]={"+","-","*","/","++","--"};
5.关系运算符。
*relation[7]={"<","<=","=",">",">=","==","!
="};
6.分界符。
*border[7]={",",";","{","}","(",")","//"};
三、输出格式
1)若为关键字,则输出格式为
关键字float,输出为
2)若为一般标识符,则输出格式为
标识符fzu,输出为
3)若为数字,则输出格式为
数字2325,输出为<2325,数字>
4)若为算术运算符,则输出格式为<符号,算术运算符>;例:
+,输出为<+,算术运算符>
5)若为关系运算符,则输出格式为<符号,关系运算符>;例:
!
=,输出为
=,关系运算符>
6)若出错,则输出格式为
错误输入为26.,则输出为<26.,ERROR>
四、正则表达式:
标识符id->letter_(letter_|digit)*
无符号数number->digitoptitionalfractionoptionalexponent
空白符ws->(blank|tab|newline)+
关系运算符relop-><|>|<=|>=|=|!
=
运算符operator->+|-|*|/|++|--
五、DFA状态转换图
六、流程图
七、实验结果
实验环境:
MicrosoftWindows7下的MicrosoftVisualStudio2010
输入
输出
输入
输出
输入
输出
八、结果分析
用格式为.txt的文件输入,一个个字符去识别,根据DFA的状态图实现跳转,把未进入接受状态的单元存放进一个数组,到达接受状态,将识别出来的词和属性一起输出。
其中识别得到的id与keyword转换过程相同,故最后得到的结果还要再判断是标识符还是关键字。
由于关键词有限,可以建个表存放关键字,通过查表实现判断关键字。
运算符和分隔符是有限的,所以把它们罗列去判断,只要是符合条件就接收。
九、实验总结
实验是理论的实践,但是通过实验加深了我们对理论课知识的理解和运用,词法分析器更是如此。
对输入的程序进行分析,将关键字,保留字与系统标识符分开,并对属性进行说明。
更通俗的来说,也就是编写一个程序,可以实现这个功能。
通过这个实验,现在我们知道了,如何用正则表达式去识别我们想要识别的单词。
但如何用程序去实现整个识别过程,又该如何去一步步执行识别呢?
最简单的方法,一个字符一个字符的读入,每读入一个字符,识别过程进入一个特定的状态,按照一定的次序在一系列状态间转换后,字符全部读入,状态也走入了终态。
那么好了,一个单词识别完毕,这就给我们启示,从一个状态转换图可以较容易的实现程序化的识别工作。
这样我们就知道如何从一个状态图去写程序了。
十、实验代码
#include"stdafx.h"
#include
#include
#include
#include
#include
usingnamespacestd;
ifstreamfp("in.txt",ios:
:
in);
charcbuffer;
char*key[53]={"auto","bool","break","case","catch","char","class","const","continue","default","delete","do","double","else","enum","extern","false","float","for","friend","goto","if","inline","int","long","namespace","new","operator","private","protected","public","register","return","short","signed","sizeof","static","struct","switch","template","this","throw","true","try","typedef","typename","union","unsigned","using","virtual","void","volatile","while"};//关键字
char*border[7]={",",";","{","}","(",")","//"};//分界符
char*arithmetic[6]={"+","-","*","/","++","--"};//算术运算符
char*relation[7]={"<","<=","=",">",">=","==","!
="};//关系运算符
intsearch(charsearchchar[],intwordtype)//search函数查表匹配
{
inti=0,t=0;
switch(wordtype)
{
case1:
{for(i=0;i<=52;i++)//关键字
{
if(strcmp(key[i],searchchar)==0)
return(i+1);
}
return(0);}
case2:
{
for(i=0;i<=6;i++)//分界符
{
if(strcmp(border[i],searchchar)==0)
return(i+1);
}
return(0);
}
case3:
{
for(i=0;i<=5;i++)//运算符
{
if(strcmp(arithmetic[i],searchchar)==0)
return(i+1);
}
return(0);
}
case4:
{
for(i=0;i<=6;i++)//关系运算符
{
if(strcmp(relation[i],searchchar)==0)
return(i+1);
}
return(0);
}
}
}
charalphaprocess(charbuffer)//字符处理过程
{
inti=-1;
charalphatp[20];
while(buffer=='_'||(isalpha(buffer))||(isdigit(buffer)))
//这两个函数分别是判字符和判数字函数位于ctype.h中
{
alphatp[++i]=buffer;
buffer=fp.get();
}
alphatp[i+1]='\0';//在末尾添加字符串结束标志
if(search(alphatp,1))
cout<<"<"< else { cout<<"<"< } return(buffer); } chardigitprocess(charbuffer)//数字处理过程 { inti=-1; chardigittp[20]; while((isdigit(buffer))) { digittp[++i]=buffer; buffer=fp.get(); } if(buffer=='.') { digittp[++i]=buffer; buffer=fp.get(); if(! isdigit(buffer)) { digittp[i+1]='\0'; cout<<"<"< return(buffer); } else { digittp[++i]=buffer; buffer=fp.get(); while(isdigit(buffer)) { digittp[++i]=buffer; buffer=fp.get(); } } } elseif(buffer=='E') { digittp[++i]=buffer; buffer=fp.get(); if(buffer=='+'||buffer=='-') { digittp[++i]=buffer; buffer=fp.get(); } if(isdigit(buffer)) { digittp[++i]=buffer; buffer=fp.get(); } else{ digittp[i+1]='\0'; cout<<"<"< return(buffer);} } digittp[i+1]='\0'; cout<<"<"< return(buffer); } charotherprocess(charbuffer)//分界符、运算符等 { inti=-1; charothertp[20]; othertp[0]=buffer; othertp[1]='\0'; if(search(othertp,3))//运算符 { buffer=fp.get(); othertp[1]=buffer; othertp[2]='\0'; if(search(othertp,3))//判断该运算符是否是 //由连续的两个字符组成的 { cout<<"<"< buffer=fp.get(); gotoout; } else//单字符逻辑运算符 { othertp[1]='\0'; cout<<"<"< gotoout; } } if(search(othertp,4))//关系运算符 { buffer=fp.get(); othertp[1]=buffer; othertp[2]='\0'; if(search(othertp,4))//判断该关系运算符是否是 //由连续的两个字符组成的 { cout<<"<"< buffer=fp.get(); gotoout; } else//单字符逻辑运算符 { othertp[1]='\0'; cout<<"<"< gotoout; } } if(buffer=='! ')//"=="的判断 { buffer=fp.get(); if(buffer=='=') { othertp[1]=buffer; othertp[2]='\0'; cout<<"<"< buffer=fp.get();} else{cout<<"<"< 的处理输出 buffer=fp.get();} gotoout; } else { if(search(othertp,2))//分界符 { cout<<"<"< buffer=fp.get(); gotoout; } } if((buffer! ='\n')&&(buffer! ='')) cout<<"<"< buffer=fp.get(); out: return(buffer); } voidmain() { if(! fp) cout<<"文件打开错误! ! "< else { fp.get(cbuffer); while(! fp.eof()) { if(isalpha(cbuffer)||cbuffer=='_')//isalpha函数判断输入是否为字母 { cbuffer=alphaprocess(cbuffer);//字符处理(判断标示符和关键字) } elseif(isdigit(cbuffer))//isdigit函数判断输入是否为数字 { cbuffer=digitprocess(cbuffer);//数字处理 } else cbuffer=otherprocess(cbuffer);//其他符号处理(各种运算符) } } cout<<"完成\n"; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 实验 词法 分析
![提示](https://static.bdocx.com/images/bang_tan.gif)