编译原理报告 5Word下载.docx
《编译原理报告 5Word下载.docx》由会员分享,可在线阅读,更多相关《编译原理报告 5Word下载.docx(35页珍藏版)》请在冰豆网上搜索。
![编译原理报告 5Word下载.docx](https://file1.bdocx.com/fileroot1/2022-10/12/d3a10ee5-25e4-4a7c-8317-33ff35de1526/d3a10ee5-25e4-4a7c-8317-33ff35de15261.gif)
>
>
==;
()#
(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:
ID=letter(letter|digit)*
NUM=digitdigit*
(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。
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
#
2.3词法分析程序的功能
输入:
所给文法的源程序字符串。
输出:
二元组(syn,token或sum)构成的序列。
其中:
syn为单词种别码;
token为存放的单词自身字符串;
sum为整型常数
例如:
对源程序
beginx:
=9;
ifx>
0:
thenx:
=2*x+1/3;
end#
的源文件,经词法分析后输出如下序列:
(1,begin)(10,’x’)(18,:
=)(11,9)(26,;
)(2,if)……
3、词法分析程序的算法思
算法的基本任务是字符串表示的源程序中识别处具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字种类,拼出相应的单词符号。
3.1主程序示意图
主程序示意图如图1所示,其中初值包括如下两个方面。
(1)关键字表的初值
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:
Char*rwtab[6]={“begin”,”if”,”then”,”while”,”do”,”end”};
(2)程序中需要用到的主要变量为syn,token,和sum。
3.2扫描子程序的算法思想
首先设置3个变量:
1.token用来存放构成单词符号的字符串;
2.sum用来存放整型单词;
3.syn用来存放单词符号的种别码。
扫描子程序的主要流程图如图所示:
4、实验结果
1.输入beginx:
=9;
0thenx:
=2*x+1/3;
end#结果如下
2.输入begina=9end#结果如下
5、实验感想及总结
本次实验主要是针对词法进行分析,让我对于词法分析的理论基础有了更深刻的认知。
词法分析程序的功能是从左到右扫描源程序字符串,根据语言的词法规则识别出各类单词符号,并以二元组(单词种别,单词自身值)的形式输出。
在课程上主要是理解了词法分析的作用以及其工作的原理,对于其具体的实现还不是很清楚,在本次实验中自己对于词法程序的编写是我将理论与实际相结合,对于具体的输入输出都有了很深刻的概念。
但是在实验中也存在一些不足,比如,这只是针对其中一组关键字来实现的,如果换一组关键字,则需要重新编写程序。
然而,LEX词法生成器能够很方便的实现,对此可以进行改进,“实践是检验真理的唯一标准”,对此我们应该谨记,从而继续对于实验中的不足进行改进。
6、源代码
#include<
stdio.h>
string.h>
stdlib.h>
#defineKEY_WORD_END"
waitingforyourexpanding"
/*定义关键字结束标识符*/
typedefstruct/*单词二元组的结构*/
{
intsyn;
char*word;
}WORD;
charinput[255];
/*输入缓冲区*/
chartoken[255]="
"
/*单词缓冲区*/
intp_input;
/*输入缓冲区指针*/
intp_token;
/*单词缓冲区指针*/
charch;
/*当前读入字符*/
constchar*Keyword[]={"
begin"
"
if"
then"
while"
do"
end"
KEY_WORD_END};
/*可扩充关键字数组*/
charm_getch();
voidgetbc();
voidconcat();
intletter();
intdigit();
intreserve();
voidretract();
charm_getch()/*从输入缓冲区读取一个字符到ch*/
ch=input[p_input];
p_input=p_input+1;
return(ch);
}
voidgetbc()/*去掉空白符号*/
while(ch=='
'
||ch==10)
{
}
voidconcat()/*拼接单词*/
token[p_token]=ch;
p_token=p_token+1;
token[p_token]='
\0'
intletter()/*判断是否是字母*/
if((ch>
='
a'
&
ch<
z'
)||(ch>
A'
Z'
))
return1;
else
return0;
intdigit()/*判断是否是数字*/
if(ch>
0'
9'
intreserve()/*检索关键字表格*/
inti=0;
while(strcmp(Keyword[i],KEY_WORD_END))
if(!
strcmp(Keyword[i],token))
returni+1;
i=i+1;
return10;
voidretract()/*回退一个字符*/
p_input=p_input-1;
WORD*scaner()
WORD*myword=newWORD;
myword->
syn=10;
word="
p_token=0;
m_getch();
getbc();
if(letter())
while(letter()||digit())
concat();
retract();
syn=reserve();
word=token;
return(myword);
elseif(digit())
while(digit())
syn=20;
elseswitch(ch)
case'
m_getch();
if(ch=='
syn=39;
=="
syn=21;
="
break;
+'
myword->
syn=22;
+"
-'
syn=23;
-"
*'
syn=24;
*"
/'
syn=25;
/"
('
syn=26;
("
)'
syn=27;
)"
['
syn=28;
["
]'
syn=29;
]"
{'
syn=30;
{"
}'
syn=31;
'
syn=32;
'
syn=33;
syn=34;
syn=37;
syn=35;
syn=38;
syn=36;
!
m_getch(