实验一 词法分析.docx
《实验一 词法分析.docx》由会员分享,可在线阅读,更多相关《实验一 词法分析.docx(17页珍藏版)》请在冰点文库上搜索。
![实验一 词法分析.docx](https://file1.bingdoc.com/fileroot1/2023-5/2/7d3aea51-77ad-49fa-9004-06e862482dae/7d3aea51-77ad-49fa-9004-06e862482dae1.gif)
实验一词法分析
实验一词法分析
1.实验目的
过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词(token),即基本保留字、标识符、常量、运算符、分隔符五大类,并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
2.实验分工
个人
3.程序说明:
词法分析器输出类型说明:
1关键字
2字母
3数字
4运算符
5标识符
6c++输入符号
7无法识别的
以及各个字母数字所在内码
intIskey(stringc)//关键字判断
建立数组存放关键字,在分析读取中使字符拼接并判断是否一致,是则返回1,否则为0
intIsLetter(charc)//判断是否为字母
定义字母的范围,包括大小写,是则返回1,否则为0
intIsDigit(charc)//判断是否为数字
定义数字的范围,包括0~9,是则返回1,否则为0
voidanalyse(FILE*fpin)//分析文件函数
首先定义字符ch以及string类的arr
围绕着fgetc()方法随着指针一步步分析
首先剔除注释换行tab
而后验证关键词,数字,字母的判断
利用SWITCH()方法,列举一系列的case进行分类和输出
分别有各种标识符,运算符,以及<=<<<和>=>>>区分
而后在case’/’中识别//和/**/类注释并剔除
规定{以及(出现的频率匹配}和),只输出最后一个的}和)是否匹配成功验证分析的代码的完整性
Intmain()主函数
定义数组存放用户输入的地址进行验证正确性和开始分析
4.其他说明:
可选功能的实现介绍:
(1)可以实现过滤所有注释,包括//以及/**/类注释
(2)可以识别负号
是
否
(3)可以配对()以及{},检查代码的正确性
编程中遇到的主要问题:
曾遇到标识符无限分析,无法有效结束程序等
可改进的地方:
继续添加各种标识符添加无符号数实数辨别等
答辩后添加功能:
识别字母数字所在的内码,完善功能
5.运行结果截图显示
6.源程序:
要求有一定的注释
#include
#include
usingnamespacestd;
#defineMAX18
charch='';
stringkey[18]={"include","begin","end","if","then","else","while","write","read","do","call","const","char","until","edure","repeat","int","void"};
stringid[100]={""};//字母内码地址数组
intidd[100]={0};//数字内码地址数组
intcount1=0;//判断字母内码
intcount2=0;//判断数字内码
boolb=false;
intIskey(stringc)//关键字判断
{
inti;
for(i=0;i{
if(key[i].compare(c)==0)
return1;
}
return0;
}
intIsLetter(charc)//判断是否为字母
{
if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A')))
return1;
else
return0;
}
intIsDigit(charc)//判断是否为数字
{
if(c>='0'&&c<='9')
return1;
else
return0;
}
voidanalyse(FILE*fpin)//分析文件函数
{
inta=0,b=0,c=0,d=0;
stringarr="";
ch=fgetc(fpin);//继续读下一个字符
while((ch!
=-1))//获取内容
{
arr="";
if(ch==''||ch=='\t'||ch=='\n')//过滤换行符空格等不在分析范围符号
{ch=fgetc(fpin);}
elseif(IsLetter(ch))
{
while(IsLetter(ch)||IsDigit(ch))
{
arr=arr+ch;
ch=fgetc(fpin);
}
if(Iskey(arr))//关键词判断
{
cout<<"(1,"<}
else//输出非关键词并输出记录内码地址
{
for(inti=0;i<100;i++)//
{
if(id[i]==arr)
{
cout<<"(2,"<b=true;
break;
}
}
if(!
b)
{
id[count1]=arr;
cout<<"(2,"<count1++;
}
}
b=false;
}
elseif(IsDigit(ch))//数字判断
{
while(IsDigit(ch))
{
arr=arr+ch;
ch=fgetc(fpin);
}
if(ch=='.')
{
arr=arr+ch;
ch=fgetc(fpin);
while(IsDigit(ch))
{
arr=arr+ch;
ch=fgetc(fpin);
}
}
idd[count2]=atoi(arr.c_str());//开始记录数字内码
cout<<"(3,"<count2++;
}
else
switch(ch)
{
case'-':
//判断负号
{
ch=fgetc(fpin);
if(IsDigit(ch))
{
while(IsDigit(ch))
{
arr=arr+ch;
ch=fgetc(fpin);
}
if(ch=='.')
{
arr=arr+ch;
ch=fgetc(fpin);
while(IsDigit(ch))
{
arr=arr+ch;
ch=fgetc(fpin);
}
}
idd[count2]=atoi(arr.c_str());//开始记录数字内码
cout<<"(3,-"<count2++;
}
else
{
cout<<"(4,"<<"-"<<""")"<}
}
break;
case'+':
case'*':
case'=':
cout<<"(4,"<ch=fgetc(fpin);
break;
case'(':
{
a++;
cout<<"(5,"<ch=fgetc(fpin);
}
break;
case')':
{
b++;
if(a==b)
{
cout<<"(5,"<}
else
{
cout<<"(5,"<}
ch=fgetc(fpin);
}
break;
case'[':
case']':
case';':
case'.':
case'"':
case',':
cout<<"(5,"<ch=fgetc(fpin);
break;
case'{':
{
c++;
cout<<"(5,"<ch=fgetc(fpin);
}
break;
case'}':
{
d++;
if(a==b)
{
cout<<"(5,"<}
else
{
cout<<"(5,"<}
ch=fgetc(fpin);
}
break;
case'>':
//判断是输入符还是运算符
{
ch=fgetc(fpin);
if(ch=='=')
{
cout<<"(4,"<<">="<<""")"<ch=fgetc(fpin);
}
if(ch=='>')
{
cout<<"(6,"<<">>"<<""")"<ch=fgetc(fpin);
}
else
{
cout<<"(4,"<<">"<<""")"<ch=fgetc(fpin);
}
}
break;
case'<':
{
ch=fgetc(fpin);
if(ch=='=')
{
cout<<"(4,"<<"<="<<""")"<ch=fgetc(fpin);
}
elseif(ch=='<')
{
cout<<"(6,"<<"<<"<<""")"<ch=fgetc(fpin);
}
elseif(ch=='>')
{
cout<<"(4,"<<"<>"<<""")"<ch=fgetc(fpin);
}
else
{
cout<<"(4,"<<"<"<<""")"<ch=fgetc(fpin);
}
}
break;
case'/':
//剔除注释
{
ch=fgetc(fpin);
if(ch=='*')
{
ch=fgetc(fpin);
for(;;)
{
ch=fgetc(fpin);
if(ch=='*')
{
ch=fgetc(fpin);
if(ch=='/')
{
ch=fgetc(fpin);
break;
}
}
}
}
elseif(ch=='/')
{
for(;;)
{
ch=fgetc(fpin);
if(ch=='\n')
{
ch=fgetc(fpin);
break;
}
}
}
else
{
cout<<"(4,"<<"/"<<""")"<ch=fgetc(fpin);
}
}
break;
default:
cout<<"(7,"<ch=fgetc(fpin);
}
}
}
intmain()
{
charin_fn[30];//存放地址
FILE*fpin;
cout<<"请输入代码地址:
";
for(;;)
{
cin>>in_fn;
if((fpin=fopen(in_fn,"r"))!
=NULL)//判断文件是否存在
break;
else
cout<<"文件路径错误!
";
}
cout<<"\n分析如下"<analyse(fpin);//开始分析
fclose(fpin);
cout<}
8:
测试语句
#include
usingnamespacestd;
intmain()
{
-22.3
12323
//SADSDASDASDA
/*
ASD
DASD*
*/
cout<<"howdoyoudo"<return0;
}