词法分析器C语言编译原理.docx
《词法分析器C语言编译原理.docx》由会员分享,可在线阅读,更多相关《词法分析器C语言编译原理.docx(12页珍藏版)》请在冰豆网上搜索。
词法分析器C语言编译原理
编译原理实验报告
院(系):
信息技术学院
专业:
学生姓名:
_
班级:
__ 学号:
题目:
词法分析器_____
起迄日期:
_2012-11-21___
设计地点:
指导教师:
完成日期:
2012年11月21日
C.1词法分析器
C.1.1实验目的
设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
C.1.2实验要求
C.1.2.1待分析的简单语言的词法
(1)关键字:
benginifthenwhiledoendstartfor
所有的关键字都是小写。
(2)运算符和界符:
:
=+-*/<<=<>>>==;()#!
@&
(3)其他单词是标志符(ID)和整形常数(NUM),通过以下正规式定义:
ID=letter(letter|digit)*
NUM=digitdigit*
(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。
C.1.2.2各种单词符号对应的种别码
单词符号
种别码
单词符号
种别码
begin
1
:
17
if
2
:
=
18
then
3
<
20
while
4
<>
21
do
5
<=
22
end
6
>
23
Letter(letter|digit)
10
>=
24
digitdigit*
11
=
25
+
13
;
26
-
14
(
27
*
15
)
28
/
16
#
0
!
29
@
30
^
30
&
30
C.1.2.3词法分析程序的功能
输入:
所给文法的源程序字符串。
输出:
二元组(syn,token或sum)构成的序列。
其中:
syn为单词种别码;
token为存放的单词自身字符串;
sum为整形常数。
功能测试:
(1)程序调试界面如下:
(2)输入字符串beginx:
=9;forx>0thenx:
=2*x@1/3;end#
其结果如下图所示:
(3)输入字符串:
!
@^其结果如下图所示:
(4)输入字符串where#其输出结果如下图所示:
(5)输入字符串1234#其结果显示如下:
(6)输入字符串@#其结果显示如下:
(7)输入字符串^^^^^^#其结果显示如下:
C.1.3词法分析程序的基本思想
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想示根据扫描到单词符号的第一字符的种类,拼出相应的单词符号。
1.主程序示意图
主程序示意图如图C。
1所示。
其中初值包括如下两个方面:
(1)关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:
char*rwtab[6]{“begin”,”if”,”then”,”while”,”do”,”end”,“start”,“for”};
图C.1词法分析主程序示意图
(2)程序中需要用到的主要变量为syn,token和sum。
2.扫描子程序的算法思想
首先设置3个变量:
a.token用来存放构成单词符号的字符串;b.sum用来存放整形单词;c.syn用来存放单词符号的种别码。
扫描子程序主要部分流程如图C.2所示。
图C.2词法分析程序流程
C.1.4词法分析程序源代码
#include
#include
charprog[80],token[6];
charch;
intsyn,p,m,n,sum;
char*rwtab[8]={"begin","if","then","while","do","end","start","for"};
main()
{
p=0;
printf("\n你好,请输入:
");
do
{
ch=getchar();
prog[p++]=ch;
}while(ch!
='#');
p=0;
do
{
scaner();
switch(syn)
{
case11:
printf("(%d,%d)",syn,sum);break;
case-1:
printf("inputerror\n");break;
default:
printf("(%d,%s)",syn,token);
}
}while(syn!
=0);
getch();
}
/*词法扫描程序:
*/
scaner()
{
for(n=0;n<8;n++)
token[n]=NULL;
m=0;
ch=prog[p++];
while(ch=='')ch=prog[p++];
if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A'))
{
while((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A')||(ch<='9'&&ch>='0'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
ch=prog[--p];
syn=10;
for(n=0;n<8;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
else
if((ch<='9'&&ch>='0'))
{
sum=0;
while((ch<='9'&&ch>='0'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
ch=prog[--p];
syn=11;
}
else
switch(ch)
{
case'<':
m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
else
if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
ch=prog[--p];
}
break;
case'>':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
ch=prog[--p];
}
break;
case':
':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
ch=prog[--p];
}
break;
case'+':
syn=13;token[0]=ch;break;
case'-':
syn=14;token[0]=ch;break;
case'*':
syn=15;token[0]=ch;break;
case'/':
syn=16;token[0]=ch;break;
case':
=':
syn=18;token[0]=ch;break;
case'<>':
syn=21;token[0]=ch;break;
case'<=':
syn=22;token[0]=ch;break;
case'>=':
syn=24;token[0]=ch;break;
case'=':
syn=25;token[0]=ch;break;
case';':
syn=26;token[0]=ch;break;
case'(':
syn=27;token[0]=ch;break;
case')':
syn=28;token[0]=ch;break;
case'#':
syn=0;token[0]=ch;break;
case'!
':
syn=29;token[0]=ch;break;
case'@':
syn=30;token[0]=ch;break;
case'^':
syn=30;token[0]=ch;break;
case'&':
syn=30;token[0]=ch;break;
default:
syn=-1;
}
}