词法分析编译原理论文Word下载.docx
《词法分析编译原理论文Word下载.docx》由会员分享,可在线阅读,更多相关《词法分析编译原理论文Word下载.docx(16页珍藏版)》请在冰豆网上搜索。
ID
=
letter
(letter
|
digit)*
NUM
digit
digit*
(4).空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2各种单词符号对应的种别码
表2-2种别码
单词符号
种别码
begin
1
(
26
if
2
)
27
then
3
[
28
while
4
]
29
do
5
{
30
end
6
}
31
lishuman
7
32
lishuman2015041886
8
:
33
10
;
34
11
>
35
=
21
<
36
+
22
=
37
-
23
38
*
24
==
39
/
25
!
40
2.3词法分析程序的功能
输入:
所给文法的源程序字符串。
输出:
二元组(syn,token或sum)构成的序列。
其中:
syn为单词种别码;
token为存放的单词自身字符串;
sum为整型常数。
例如:
对源程序begin
x:
=9:
x>
9
then
=2*x+1/3;
#的源文件,经过词法分析后输出如下序列:
(1,begin)(10,x)(18,:
=)(11,9)(26,;
)(2,if)……
2.4识别语言单词的状态转换图
识别语言单词的状态转换图如下图2-4所示:
状态0为初态,凡带双圈者为终态。
图2-4识别语言单词的状态转换图
三、词法分析程序的算法思想
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想
是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1主程序示意图:
图3-1主程序示意图
其中初始包括以下两个方面:
(1).
关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程
序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标
识符。
关键字表为一个字符串数组,其描述如下:
Char
*nrwtab[6]=
{“begin”,“if'
"
then”,"
while”,“do"
end"
};
(2).程序中需要用到的主要变量为syn,token和sum
3.2
扫描子程序的算法思想:
首先设置3个变量:
①token用来存放构成单词符号的字符串;
②sum用来整型单词;
③syn用来存放单词符号的种别码。
图3-2扫描子程序主要部分流程图
四、运行结果
4.1.安装Linux虚拟机(已经配置好虚拟机的可以跳过此步骤)
1.安装VMware-player
2.解压Ubuntu16.04_64-bit.rar
3.在VMware-player中设置虚拟机:
点击“打开已经存在的虚拟机”,然后选择“Ubuntu16.04_64-bit.vmx”。
4.启动虚拟机,查看是否安装成功。
4.2.创建工作目录
在用户家目录下建立lishuman文件夹,建立scaner.c文件编写代码,建立testin.txt输入程序。
4.3.词法分析
1.打开命令行。
cdlishuman/回车,进入lishuman目录
2.编译程序。
编译scaner.c文件。
图4-3编译scaner.c文件
4.4.编译运行程序
testin.txt是词法分析器的输入程序(即输入的源程序,此程序由学生给出)。
运行后,自动在
lishuman目录下生成result.txt文件。
(testin.txt和result.txt文件都可由记事本查看内容)
图4-4.1testin.txt文件内容
图4-4.2result.txt文件内容
如果testin.txt中输入有误
图4-4.3testin.txt错误文件内容
则运行时显示:
图4-4.4result.txt错误文件内容
五、源程序
#include<
stdio.h>
stdlib.h>
string.h>
#define_KEY_WORD_END"
waitingforyourexpanding"
typedefstruct
inttypenum;
char*word;
}WORD;
charinput[255];
//输入缓冲区
chartoken[255]="
"
//单词缓冲区
intp_input;
//输入缓冲区指针
intp_token;
//单词缓冲区指针
charch;
//当前读入字符
char*KEY_WORDS[]={"
begin"
if"
then"
while"
do"
lishuman"
lishuman2015041886"
_KEY_WORD_END};
//关键字数组
WORD*scaner(WORD*word);
//词法扫描函数
intmain(intargc,char*argv[])
intover=1;
WORD*oneword=calloc(1,sizeof(WORD*));
//printf("
EnterYourwords(endwith$):
);
//scanf("
%[^$]s"
input);
FILE*fin;
charbuffer[1000];
if((fin=fopen("
testin.txt"
r"
))==NULL)
{
printf("
Cannotopenthefile!
\n"
exit(-1);
}
while(fgets(buffer,100,fin)!
=NULL)
strcat(input,buffer);
fclose(fin);
FILE*fout;
if((fout=fopen("
result.txt"
w"
p_input=0;
printf("
Yourwords:
\n%s\n"
while(over<
1000&
&
over!
=-1){//对源程序进行分析
oneword=scaner(oneword);
//获得一个新单词
if(oneword->
typenum<
1000)
fprintf(fout,"
(%d,%s)"
oneword->
typenum,oneword->
word);
//打印种别码和单词自身的值
over=oneword->
typenum;
fclose(fout);
\npressdone."
//从缓冲区读取一个字符到ch中
charm_getch(){
ch=input[p_input];
p_input=p_input+1;
return(ch);
//去掉空白符号
voidgetbc(){
while(ch=='
'
||ch==10){
ch=input[p_input];
p_input=p_input+1;
//拼接单词
voidconcat(){
token[p_token]=ch;
p_token=p_token+1;
token[p_token]='
\0'
//判断是否字母
intletter(){
if(ch>
='
a'
ch<
z'
||ch>
A'
Z'
)return1;
elsereturn0;
//判断是否数字
intdigit(){
0'
9'
//检索关键字表格
intreserve(){
inti=0;
while(strcmp(KEY_WORDS[i],_KEY_WORD_END)!
=0){
if(!
strcmp(KEY_WORDS[i],token)){
returni+1;
}
i=i+1;
return10;
//回退一个字符
voidretract(){
p_input=p_input-1;
//数字转换成二进制
char*dtb(){
returnNULL;
//词法扫描程序:
WORD*scaner(WORD*word){
WORD*myword=word;
myword->
typenum=10;
word="
p_token=0;
m_getch();
getbc();
if(letter()){
while(letter()||digit()){
concat();
m_getch();
retract();
myword->
typenum=reserve();
word=token;
return(myword);
elseif(digit()){
while(digit()){
//retract();
if(letter())
{
myword->
typenum=-1;
ERROR"
printf("
In%s(),line=%d,invalidvariable,error!
__func__,__LINE__);
exit(0);
}else
retract();
typenum=20;
}
elseswitch(ch){
case'
if(ch=='
){
myword->
typenum=39;
=="
return(myword);
}
retract();
myword->
typenum=21;
="
return(myword);
break;
+'
typenum=22;
+"
-'
typenum=23;
-"
*'
typenum=24;
*"
/'
typenum=25;
/"
('
typenum=26;
("
)'
typenum=27;
)"
['
typenum=28;
["
]'
typenum=29;
]"
{'
typenum=30;
{"
}'
typenum=31;
}"
'
typenum=32;
'
typenum=33;
typenum=34;
typenum=37;
typenum=35;
typenum=38;
typenum=36;
typenum=40;
typenum=1000;
OVER"
default:
六、实验总结
通过这次实验,我对词法分析器有了一定的了解,进一步的巩固了这部分的知识。
既通过这次用C语言对词法分析程序的编制,回顾了C语言的编程方法;
又加深了对词法分析原理的理解和词法分析的实现过程,掌握了编译程序的实现方法和技术,懂得了词法分析器的工作原理。
在编程过程中,遇到了不少的问题,在同学的帮助下,问题一步一步的得到了解决。
先从实现最简单的扫描和输出开始,后继实现了扫描范围的扩大和输出结果的更加具体。