编译原理报告(8) 本文关键词:编译,原理,报告
编译原理报告(8) 本文简介:编译原理实验报告课程实验报告课程名称:编译原理专业班级:信息安全1302班学号:姓名:指导教师:报告日期:2015/11/8计算机科学与技术学院实验一:词法分析一、实验要求1.1待分析的简单的词法(1)关键字:beginifthenwhiledoend所有的关键字都是小写。(2)运算符和界符:=+-
编译原理报告(8) 本文内容:
编译原理实验报告
课
程
实
验
报
告
课程名称:
编译原理
专业班级:
信息安全1302班
学
号:
姓
名:
指导教师:
报告日期:
2015/11/8
计算机科学与技术学院
实验一:词法分析
一、
实验要求
1.1
待分析的简单的词法
(1)关键字:
begin
if
then
while
do
end
所有的关键字都是小写。
(2)运算符和界符
:
=
+
-
/
>
>=
=
;
(
)
#
(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:
ID
=
letter
(letter
|
digit)*
NUM
=
digit
digit*
(4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
1.2
各种单词符号对应的种别码:
表2.1
各种单词符号对应的种别码
单词符号
种别码
单词符号
种别码
begin
1
:
17
If
2
:=
18
Then
3
21
do
5
23
lettet(letter|digit)*
10
>=
24
dight
dight*
11
=
25
+
13
;
26
—
14
(
27
15
)
28
/
16
#
0
1.3
词法分析程序的功能:
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;
token为存放的单词自身字符串;
sum为整型常数。
例如:对源程序begin
x:=9:
if
x>9
then
x:=2*x+1/3;
end
#的源文件,经过词法分析后输出如下序列:
(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……
二、词法分析程序的算法思想:
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
2.1
主程序示意图:
主程序示意图如图3-1所示。其中初始包括以下两个方面:
⑴
关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下:
Charrwtab[6]
=
{“begin”,“if”,“then”,“while”,“do”,“end”,};
置初值
调用扫描子程序
输出单词二元组
输入串结束
否
是
结束
图2-1
(2)程序中需要用到的主要变量为syn,token和sum
2.2
扫描子程序的算法思想:
首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。
变量初始化
忽略空格
是否文件结束?
返回
是
是
否
字母
拼数
拼字符串
数字
其他
运算符、
符号
是否关键字?
界符等符号
报错
对不同符号给出相应的syn值
返回
syn=1111
syn=10
否
syn为对应关键字的单词种别码
是
图
2-2
三.测试结果
对源程序begin
x:=9:
if
x>9
then
x:=2*x+1/3;
end
#的源文件,经过词法分析,结果正确,与预期一致。
四.源程序
#include
#include
char
prog[80],token[8],ch;
int
syn,p,m,n,sum;
charrwtab[6]={“begin“,“if“,“then“,“while“,“do“,“end“};
main(){
p=0;
printf(“/n
ê?è?·?o?2¢ò?
#
?áê?:/n“);
do{
scanf(“%c“,prog[p++]=ch;
}while(ch!=
#
);
p=0;
do{
scaner();
switch(syn){
case
11:printf(“(
%-10d%5d
)/n“,sum,syn);
break;
case
-1:printf(“you
have
input
a
wrong
string/n“);
getch();
exit(0);
default:
printf(“(
%-10s%5d
)/n“,token,syn);
break;
}
}while(syn!=0);
getch();
}
scaner(){
sum=0;
for(m=0;m=
a
))||((ch=
A
)))
{
while(((ch=
a
))||((ch=
A
))||((ch>=
0
)
token[m++]=ch;
}
else
{
syn=20;
p--;
}
break;
case
:
:token[m++]=ch;
ch=prog[p++];
if(ch==
=
)
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
p--;
}
break;
case
>
:token[m++]=ch;
ch=prog[p++];
if(ch==
=
)
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
p--;
}
break;
case
-
:syn=14;
token[m++]=ch;
break;
case
+
:
syn=13;
token[m++]=ch;
break;
case
:
syn=15;
token[m++]=ch;
break;
case
/
:
syn=16;
token[m++]=ch;
break;
case
(
:
syn=27;
token[m++]=ch;
break;
case
)
:
syn=28;
token[m++]=ch;
break;
case
=
:
syn=25;
token[m++]=ch;
break;
case
;
:
syn=26;
token[m++]=ch;
break;
case
#
:
syn=0;
token[m++]=ch;
break;
default:
syn=-1;
break;
}
token[m++]=
/0
;
}
实验二:语法分析
一.实验目的
1)
设计并编制一个语法分析程序,加深对语法分析程序中递归下降分析方法的理解;
2)
巩固对代码生成及报错处理等理论的认识;
3)
培养对完整系统独立分析和设计的能力;
4)
培养学生独立编程的能力;
二.实验要求
利用C语言编制递归下降分析程序,并对简单语言进行语法分析。
2.1
待分析的简单语法的语法
用扩充的BNF表示如下:
(1)
::=begin
end
(2)
::={:语句}
(3)
::=
(4)
::=ID
:=
(5)
::={+|-}
(6)
::={*|/}
(7)
::=ID
|
NUM
|
(
)
2.2
语法分析程序的功能
输入单词串,以”#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出”error”
例如:
输入:
begin
a:=9;b:=0
end
#
输出:
success
输入:
begin
a=9
end
#
输出:
error
三.词法分析程序的算法思想
算法的基本任务是从字符串中表示的源程序中识别出具有独立意义的单词符号,并通过其基本文法,正确规约到开始符号。
1)
全局变量的设置
在此程序中,需要设置两个个全局变量:
关键字表retab[6]、当前识别的种别号syn。
其中retab中元素为
“begin”
“if”
“then”
“while”
“do”
“end”,在程序会扫描出标识符时,首先查关键字表。如果能找到匹配的单词,则该单词为关键字,否则为一般标识符。
syn用于每一步扫描中scanner
的返回值。在整个语法分析程序中均需要使用该全局变量。
2)
主程序main算法流程图
开始
读取字符串到inputString
int
i
=0;输入字符串长度inputLength
Scanner()
syn
==
-1
Y
N
lrparser()
结束
3)
扫描子程序scanner()的算法流程图
调用
ch
=当前第一个字符
字母
当前字符串
数字
运算符/界符
syn=种别号
当前数字
syn=相应的种别号
是否关键字
其他符号
错误
N
syn=11
Y
返回
4)
lrparser()的算法流程图
调用
syn
=
1
N
Y
scanner()
yucu()
syn
==
6
N
Y
scanner()
syn
==
0
N
Y
出错处理
成功,打印“success”
5)
语句串分析程序yucu()的算法流程图
调用
statement()
syn
==26(;)
N
scanner()
出错处理
Y
6)
statement语句分析算法流程图
调用
syn
==26(;)
scanner()
syn
==18(:=)
否
scanner()
是
出错处理
expression()
7)
expression表达式分析算法流程图
调用
term()
是否+
或-
N
Y
scanner()
出错处理
term
8)
term分析函数算法流程图
调用
factor()
是否*
或
/
N
出错处理
Scanner()
Y
9)
factor分析函数算法流程图
调用
是否标识符
Y
N
是否整常数
Y
N
是否(
Y
scanner()
;
expression()
出错处理
是否
)
scanner()
;返回
N
Y
四.实验结果
1.
输入begin
a:=9;
x:=
2*3
end
#
结果如下
2.
输入begin
a=9
end
#
结果如下
五.实验感想及总结
本次实验和第一实验一样,框架已经给出,我们需要做的是将第一个实验和第二个实验很好的结合起来。
由于第一次实验中不是按照书中的框架写出的代码,因此在第二次实验时传递参数时出现了问题,最后不得不利用全局变量syn解决。通过两次编译原理的实验,更加理解了词法语法分析的过程,促进了对课程的进一步学习。
六.源代码
#include
#include
#include
#include
char
GetChar(charinput,intindex,int
length);
int
ClearBlank(charinput,int
(*index),int
length);
int
reserve(chars);
void
lrparser(charinput,int
inputLength,intindex);
void
yucu(charinput,int
inputLength,intindex);
void
factor(charinput,int
inputLength,intindex);
void
statement(charinput,int
inputLength,intindex);
void
expression(charinput,int
inputLength,intindex);
void
term(charinput,int
inputLength,intindex);
charretab[6]={“begin“,“if“,“then“,“while“,“do“,“end“};//关键字
int
syn=0;
int
myIsAlpha(char
ch)
{
if(islower(ch)==2
||
isupper(ch)==1)
{
return
1;
}
else
{
return
0;
}
}
void
scaner(charinput,int
inputLength,intindex)
{
char
s[256]=““;
//保存当前的字符
char
ch=GetChar(input,index,inputLength);
int
nowPosition=0;
int
j=0;
if(myIsAlpha(ch)==1)
//如果是字母
{
while(((ch>=
0
//添加结束标志
j=reserve(s);
if(j==0)
{
syn=10;
}
else
{
syn=j;
}
(*index)--;
return;
}
else
//超过范围
{
s[nowPosition++]=ch;
s[nowPosition]=
/0
;//添加结束标志
j=reserve(s);
if(j==0)
{
syn=10;
}
else
{
syn=j;
}
getchar();
exit(0);
return;
}
}
else
if(ch>=
0
syn=11;
return;
}
else
//超过范围时
{
s[nowPosition]=ch;
syn=11;
return;
}
}
else
{
switch(ch)
{
case
+
:
{
syn=13;
return;
}
case
-
:
{
syn=14;
return
;
}
case
:
{
syn=15;
return
;
}
case
/
:
{
syn=16;
return
;
}
case
)
{
syn=21;
return
;
}
else
{
syn=20;
if(*index>inputLength)
{
return;
}
else
{
(*index)--;
return
;
}
}
}
case
>
:
{
ch=GetChar(input,index,inputLength);
if(ch==
=
)
{
syn=24;
return
;
}
else
{
syn=23;
if(*index>inputLength)
{
return;
}
else
{
(*index)--;
return
;
}
}
}
case
:
:
{
ch=GetChar(input,index,inputLength);
if(ch==
=
)
{
syn=18;
return
;
}
else
{
if(*index>inputLength)
{
return;
}
else
{
(*index)--;
return
;
}
}
}
case
=
:
{
syn=25;
return
;
}
case
;
:
{
syn=26;
return
;
}
case
(
:
{
syn=27;
return
;
}
case
)
:
{
syn=28;
return
;
}
case
#
:
{
syn=0;
return
;
}
case
:
{
syn=-1;
return
;
}
default:
{
printf(“(非法符号)“);
}
}
}
}
int
reserve(chars)
{
if(strcmp(s,retab[0])==0)
{
return
1;
}
else
if(strcmp(s,retab[1])==0)
{
return
2;
}
else
if(strcmp(s,retab[2])==0)
{
return
3;
}
else
if(strcmp(s,retab[3])==0)
{
return
4;
}
else
if(strcmp(s,retab[4])==0)
{
return
5;
}
else
if(strcmp(s,retab[5])==0)
{
return
6;
}
else
{
return
0;
}
}
char
GetChar(charinput,intindex,int
length)
{
if(*index
<=
length)
{
(*index)++;
return
input[(*index)-1];
}
else
return
0;
}
int
ClearBlank(charinput,int
(*index),int
length)
{
while(
(*index)
!=
length)
{
if(input[(*index)]
==32
}
else
if(
input[(*index)]
==32
getchar();
exit(0);
}
else
{
return
1;
}
}
return
0;
}
void
lrparser(charinput,int
inputLength,intindex)
{
if(syn==1)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
yucu(input,inputLength,index);
if(syn
==
6)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
if(syn==0
)
{
printf(“success/n“);
getchar();
return;
}
}
}
else
{
printf(“error!“);
return;
}
}
void
yucu(charinput,int
inputLength,intindex)
{
statement(input,inputLength,index);
while(syn==26)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
statement(input,inputLength,index);
}
return
;
}
void
statement(charinput,int
inputLength,intindex)
{
if(syn
==10)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
if(syn==18)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
expression(input,inputLength,index);
}
else
{
printf(“输出赋值号错误!/n“);
getchar();
exit(0);
}
}
else
{
printf(“输出语句错误!%d/n“,syn);
getchar();
exit(0);
}
return
;
}
void
expression(charinput,int
inputLength,intindex)
{
term(input,inputLength,index);
while(syn
==
13||
syn
==14)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
term(input,inputLength,index
);
}
return
;
}
void
term(charinput,int
inputLength,intindex)
{
factor(input,inputLength,index
);
while(syn
==
15||
syn
==16)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
factor(input,inputLength,index
);
}
return
;
}
void
factor(charinput,int
inputLength,intindex)
{
if(syn==10
||
syn==11)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
}
else
if(syn
==27)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
expression(input,inputLength,index
);
if(syn==28)
{
scaner(input,inputLength,index);
while(syn==-1)
{
scaner(input,inputLength,index);
}
}
else
{
printf(“输出)错误“);
getchar();
exit(0);
}
}
else
{
printf(“输出表达式错误“);
getchar();
exit(0);
}
return
;
}
void
main(void)
{
char
inputString[80];
int
i
=0;
int
inputLength=0;
char
ch;
printf(“请输入字符串“,islower(
a
));
printf(“请输入字符串:“);
while((ch
=getchar())
!=
10)
{
inputString[inputLength++]=ch;
}
inputLength--;
printf(“/n输出序列:“);
scaner(inputString,inputLength,while(syn==-1)//去除前面的所有空格
{
scaner(inputString,inputLength,}
lrparser(inputString,inputLength,printf(“/n谢谢使用,按任何键退出!/n“);
getchar();
}
30
/
30