词法分析实验报告.docx
《词法分析实验报告.docx》由会员分享,可在线阅读,更多相关《词法分析实验报告.docx(10页珍藏版)》请在冰豆网上搜索。
![词法分析实验报告.docx](https://file1.bdocx.com/fileroot1/2022-11/27/9d76b227-6bae-4a57-abb5-cd9a6211354e/9d76b227-6bae-4a57-abb5-cd9a6211354e1.gif)
词法分析实验报告
编译原理实验一
姓名:
朱彦荣
学号:
专业:
软件工程2
实验题目:
词法分析
完成语言:
C/C++
上级系统:
VC++
日期:
2015/11/7
词法分析
设计题目:
手工设计c语言的词法分析器
(可以是c语言的子集)
设计内容:
处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。
设计目的:
了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。
结果要求:
课程设计报告。
完成日期:
第十五周提交报告
一.分析
要想手工设计词法分析器,实现C语言子集的识别,就要明白什么是词法分析器,它的功能是什么。
词法分析是编译程序进行编译时第一个要进行的任务,主要是对源程序进行编译预处理(去除注释、无用的回车换行找到包含的文件等)之后,对整个源程序进行分解,分解成一个个单词,这些单词有且只有五类,分别是标识符、保留字、常数、运算符、界符。
以便为下面的语法分析和语义分析做准备。
可以说词法分析面向的对象是单个的字符,目的是把它们组成有效的单词(字符串);而语法的分析则是利用词法分析的结果作为输入来分析是否符合语法规则并且进行语法制导下的语义分析,最后产生四元组(中间代码),进行优化(可有可无)之后最终生成目标代码。
可见词法分析是所有后续工作的基础,如果这一步出错,比如明明是‘<=’却被拆分成‘<’和‘=’就会对下文造成不可挽回的影响。
因此,在进行词法分析的时候一定要定义好这五种符号的集合。
下面是我构造的一个C语言子集。
第一类:
标识符letter(letter|digit)*无穷集
第二类:
常数(digit)+无穷集
第三类:
保留字(32)
autobreakcasecharconstcontinue
defaultdodoubleelseenumextern
floatforgotoifintlong
registerreturnshortsignedsizeofstatic
structswitchtypedefunionunsignedvoid
volatilewhile
第四类:
界符‘/*’、‘.
<+,33>
<-,34>
<*,35>
,36>
<<,37>
<<=,38>
<>,39>
<>=,40>
<=,41>
<==,42>
=,43>
<;,44>
<(,45>
<),46>
<^,47>
<,,48>
<",49>
<',50>
<#,51>
<&,52>
<&&,53>
<|,54>
<||,55>
<%,56>
<~,57>
<<<,58>左移
<>>,59>右移
<[,60>
<],61>
<{,62>
<},63>
<\,64>
<.,65>
66>
<:
67>
68>
"[","]","{","}"
<常数99,数值>
<标识符100,标识符指针>
上述二元组中左边是单词的符号,右边为其种别码,其中常数和标识符有点特别,因为是无穷集合,因此常数用自身来表示,种别码为99,标识符用标识符符号表的指针表示(当然也可用自身显示,比较容易观察),种别码100。
根据上述约定,一旦见到了种别码syn=63,就唯一确定了‘}’这个单词。
下面是一些变量的约定:
"\?
",":
","!
"
};
staticcharIDentifierTbl[1000][50]={""};.
<+,33>
<-,34>
<*,35>
,36>
<<,37>
<<=,38>
<>,39>
<>=,40>
<=,41>
<==,42>
=,43>
<;,44>
<(,45>
<),46>
<^,47>
<,,48>
<",49>
<',50>
<#,51>
<&,52>
<&&,53>
<|,54>
<||,55>
<%,56>
<~,57>
<<<,58>左移
<>>,59>右移
<[,60>
<],61>
<{,62>
<},63>
<\,64>
<.,65>
66>
<:
67>
68>
"[","]","{","}"
<常数99,数值>
<标识符100,标识符指针>
*/
/****************************************************************************************/
"\?
",":
","!
"
};
staticcharIDentifierTbl[1000][50]={""};||ch=='\?
'||ch==':
')
{=
pProject++;
if(resourceProject[pProject]=='=')
{
syn=42;
}
else
{
pProject--;
syn=41;
}
pProject++;
return;
}
elseif(resourceProject[pProject]=='!
')
{//!
!
=
pProject++;
if(resourceProject[pProject]=='=')
{
syn=43;
}
else
{
syn=68;
pProject--;
}
pProject++;
return;
}
elseif(resourceProject[pProject]=='&')
{//&,&&
pProject++;
if(resourceProject[pProject]=='&')
{
syn=53;
}
else
{
pProject--;
syn=52;
}
pProject++;
return;
}
elseif(resourceProject[pProject]=='|')
{//|,||
pProject++;
if(resourceProject[pProject]=='|')
{
syn=55;
}
else
{
pProject--;
syn=54;
}
pProject++;
return;
}
elseif(resourceProject[pProject]=='$')
{//结束符
syn=0;//种别码为0
}
else
{//不能被以上词法分析识别,则出错。
printf("error:
thereisnoexist%c\n",ch);
exit(0);
}
}
intmain()
{
//打开一个文件,读取其中的源程序
charresourceProject[10000];
chartoken[20]={0};
intsyn=-1,i;//初始化
intpProject=0;//源程序指针
FILE*fp,*fp1;
if((fp=fopen("D:
\\","r"))==NULL)
{//打开源程序
cout<<"can'topenthisfile";
exit(0);
}
resourceProject[pProject]=fgetc(fp);
while(resourceProject[pProject]!
='$')
{//将源程序读入resourceProject[]数组
pProject++;
resourceProject[pProject]=fgetc(fp);
}
resourceProject[++pProject]='\0';
fclose(fp);
cout<"<cout<//对源程序进行过滤
filterResource(resourceProject,pProject);
cout<"<cout<pProject=0;//从头开始读
if((fp1=fopen("D:
\\","w+"))==NULL)
{//打开源程序
cout<<"can'topenthisfile";
exit(0);
}
while(syn!
=0)
{
//启动扫描
Scanner(syn,resourceProject,token,pProject);
if(syn==100)
{//标识符
for(i=0;i<1000;i++)
{//插入标识符表中
if(strcmp(IDentifierTbl[i],token)==0)
{//已在表中
break;
}
if(strcmp(IDentifierTbl[i],"")==0)
{//查找空间
strcpy(IDentifierTbl[i],token);
break;
}
}
printf("(标识符,%s)\n",token);
fprintf(fp1,"(标识符,%s)\n",token);
}
elseif(syn>=1&&syn<=32)
{//保留字
printf("(%s,--)\n",reserveWord[syn-1]);
fprintf(fp1,"(%s,--)\n",reserveWord[syn-1]);
}
elseif(syn==99)
{//const常数
printf("(常数,%s)\n",token);
fprintf(fp1,"(常数,%s)\n",token);
}
elseif(syn>=33&&syn<=68)
{
printf("(%s,--)\n",operatorOrDelimiter[syn-33]);
fprintf(fp1,"(%s,--)\n",operatorOrDelimiter[syn-33]);
}
}
for(i=0;i<100;i++)
{//插入标识符表中
printf("第%d个标识符:
%s\n",i+1,IDentifierTbl[i]);
fprintf(fp1,"第%d个标识符:
%s\n",i+1,IDentifierTbl[i]);
}
fclose(fp1);
return0;
}