编译原理课程设计IFELSE条件语句的翻译程序设计Word文档下载推荐.docx
- 文档编号:19844699
- 上传时间:2023-01-10
- 格式:DOCX
- 页数:20
- 大小:95.83KB
编译原理课程设计IFELSE条件语句的翻译程序设计Word文档下载推荐.docx
《编译原理课程设计IFELSE条件语句的翻译程序设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计IFELSE条件语句的翻译程序设计Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
布尔表达式>
THEN<
赋值语句>
ELSE<
(1)按给定的题目写出符合语法分析方法要求的文法和属性文法描述。
(2)按给定的题目给出语法分析方法的思想及分析表的设计。
(3)按给定题目给出中间代码序列的结构设计。
(4)完成相应的词法分析、语法分析和语义分析程序设计。
(5)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。
1.2开发平台
VisualC++6.0、WindowsXP
2文法及属性文法的描述
2.1文法描述
(1)S->
ifEthenBelseB
(2)E->
(A>
A)
(3)E->
(A<
(4)E->
(A)
(5)A->
d
(6)A->
num
(7)B->
{d=C}
(8)C->
A+A
(9)C->
A-A
(10)C->
A*A
(11)C->
A/A
(12)C->
A
其中,d代表变量,num代表常量(这里仅限数字),E布尔表达式,B为赋值表达式,C为算术表达式
2.2属性文法描述
(1)E->
AropA’{E.true=nextstat;
E.codebegin=nextstat;
E.false=nextstat+1;
emit(“if”A.place“rop”A’.place“goto”-);
emit(“goto”-)}
(2)E->
(A){E.place=A.place}
(3)A->
id{p=lookup(id.name);
ifp!
=nullthen
A.place=p
elseerror}
(4)B->
{d=C}{d.place=C.place}
(5)C->
AopA’{C.place=newtemp;
emit(C.place“=”A.place“op”A’.place)}
(6)C->
A{C.place=A.place}
注:
rop为>
或<
;
op为+、-、*或/
3语义分析方法的描述及分析表设计
3.1优先关系定义
X=Y表示X和Y的优先关系相等
X>
Y表示X的优先性比Y的优先性大
X<
Y表示X的优先性比Y的优先性小
(1)X=Y当且仅当G中存在产生式规则A->
…XY…
(2)X>
Y当且仅当G中存在产生式规则A->
…XB…,B=>
Y…,B≠Y
(3)X<
…BD…,B=>
…X,B≠X,D=>
Y…
3.2简单优先文法定义
若一个文法是简单优先文法必须满足以下条件:
(1)在文法符号集V中,任意两个符号之间最多只有一种优先关系成立
(2)在文法中任意两个产生式没有相同的右部
其中第一条是必须满足的,第二条若不满足则会导致规约不唯一。
3.3简单优先文法的算法步骤
首先根据已知优先文法构造相应优先关系矩阵,并将文法的产生式保存,设置符号栈S,算法步骤如下:
(1)将输入符号串a1,a2…aN#依次逐个存入符号栈S中,直到遇到栈顶符号ai的优先性>
下一个带输入符号aj时为止。
(2)栈顶当前符号ai为句柄尾,由此向左在栈中找句柄的头符号ak,即找到ak-1<
ak为止。
(3)由句柄ak…ai在文法产生式中查找右部为ak…ai的产生式,若找到则用相应左部代替句柄,若找不到则为出错,这是可以判定输入串不是该文法的句子。
(4)重复上述
(1)
(2)(3)步骤直到规约完输入符号串,栈中只剩下文法的开始符号为止。
3.4语义分析方法描述
语义分析采用基于属性文法的翻译方案,即,在语法分析过程中每进行一次规约操作则对对应产生式进行语义计算。
3.5分析表构造
3.5.1优先关系的计算
3.5.1.1定义集合
FA(S)={a|S=>
a…,S≠a,a为文法符号}
LA(S)={a|S=>
…a,S≠a,a为文法符号}
3.5.1.2改造后的优先关系计算
当文法中存在A->
…XY…时,X=Y
…XB…时,X<
FA(B)
…BD…时,LA(B)>
D且LA(B)>
FA(D)
3.5.2分析表结构
分析表采用二维数组存储方式,文法中的每一个符号对应数组a中的一个位置,
而a[i][j]代表第i个和第j个的优先关系:
(1)a[i][i]=0无优先关系
(2)a[i][i]=1i对应元素优先级小于j的
(3)a[i][i]=2i对应元素优先级大于j的
(4)a[i][i]=3i对应元素优先级等于j的
而在分析过程中规约产生式的选择则在语法分析过程中,在语法分析过程中实现。
分析表最终结果如下:
intanltable[22][22]={
/*S*/{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
/*if*/{0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*E*/{0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*then*/{0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
/*B*/{0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
/*else*/{0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0},
/*(*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*)*/{0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
/*>
*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*<
/*=*/{0,0,0,0,0,0,0,0,0,0,0,1,1,1,3,0,0,0,0,0,0,0},
/*A*/{0,0,0,0,0,0,0,3,3,3,0,0,0,0,0,0,2,3,3,3,3,0},
/*d*/{0,0,0,0,0,0,0,2,2,2,3,0,0,0,0,0,2,2,2,2,2,0},
/*num*/{0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,2,2,2,2,2,0},
/*C*/{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0},
/*{*/{0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0},
/*}*/{0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2},
/*+*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*_*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/***/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*/*/{0,0,0,0,0,0,0,0,0,0,0,3,1,1,0,0,0,0,0,0,0,0},
/*#*/{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
//0-error,1=<
2=>
3==
4中间代码形式描述及结构设计
四元式是一种比较普遍采用的中间代码形式。
四元式的四个组成成分是:
算符op,第一和第二运算对象ARG1和ARG2及运算结果RESULT。
运算对象和运算结果有时指用户自己定义的变量,有时指编译程序引进的临时变量。
例如:
a=b*c+b*d的四元式表示如下:
(1)(*,b,c,t1)
(2)(*,b,d,t2)
(3)(+,t1,t2,t3)
(4)(=,t3,-,a)
四元式和三元式的主要不同在于,四元式对中间结果的引用必须通过给定的名字,而三元式是通过产生中间结果的三元式编号。
也就是说,四元式之间的联系是通过临时变量实现的。
5编译系统的概要设计
(1)系统主要分为两个模块:
词法分析和语法分析(包括语义分析)。
并且在分析过程中将词法分析产生的单词输出到文件,语法分析过程中分析栈的变化情况输出到文件。
(2)系统设计采用过程化的设计方法,将词法分析、语法分析等功能模块在独立的过程中实现。
(3)系统概要结构如下:
1)预定义模块
2)词法分析模块
3)语法分析模块
4)其他辅助模块
5)主程序模块(主要指程序入口函数main())
各模块调用关系如下:
预定义
主程序
语法分析
词法分析
其他辅助模块
6算法描述
6.1预定义模块
预定义模块主要包括宏定义、常量定义、类型定义以及全局变量定义等。
具体如下:
(1)宏定义
#defineOK1//正常
#defineERROR-1//出错
#defineFAILURE-1//分析失败
(2)类型定义
structatt
{//名字表类型
stringsname;
charselect;
charaddre;
typedefstructSqStack
{
char*base;
char*top;
intstacksize;
}SqStack;
//栈定义
(3)全局变量
intlineno=1;
//输出时的当前行号
charch;
//当前字符
charallname[30][30];
//单词全名
charout[30][30];
//保存单词简称
attattname[40];
//名字表
(4)优先关系表初始化(见3.5.2)
6.2词法分析
词法分析主要为analysis(ifstream&
fin,ofstream&
fout)函数,其中fin为输入文件流,fout为单词输出文件流。
辅助函数为judge(char*string),判断单词是否为关键字。
分析算法如下描述:
while(true)
{
字符串存放临时数组temp;
if(到文件末尾)break;
读取一个字符到ch;
if(ch是换行){lineno+=1;
}
elseif(ch是字符)
{
while(ch是字符或数字)
{
ch存入temp;
读取下一个字符;
判断temp是否为关键字,并根据判断结果使temp入名字表并设置正确的属性。
elseif(ch是数字)
while(ch是数字)
temp入名字表并设置正确的属性。
elseif(ch为其他合法字符(如:
>
<
=等等))填入名字表。
else输出错误,无法识别的字符。
6.3语法分析
语法分析主要为laynax(ofstream&
f)函数,其中,f为栈变化情况输出文件。
其他辅助函数为除judge(char*string)外的其他所有辅助函数。
语法分析的过称描述如下:
初始化分析栈;
while(还有单词)
判断当前栈顶单词与输入单词的优先级;
if(<
||=)当前符号入栈
elseif(>
)
while(栈顶元素优先级等于输入单词)
保存输入单词;
置输入单词为栈顶单词;
栈顶元素出栈;
判断保存单词串是否为句柄;
if(是句柄)
进行规约;
进行语义规则计算;
输出栈的变化情况;
使规约后单词为新的输入符号;
else
输出规约出错;
输出输入单词错误;
6.4其他模块
其他模块描述如下:
(1)栈操作模块
voidInitStack(SqStack&
S)
{//栈初始化
S.base=(char*)malloc(STACK_INIT_SIZE*sizeof(char));
//分配存储空间
if(!
S.base)
exit(OVERFLOW);
//为栈S分配存储空间失败
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
intpush(SqStack&
S,charch)//将元素e插入到栈S中,成为新的栈顶元素
if(S.top-S.base>
S.stacksize)//判定栈是否满
{
S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT*sizeof(char)));
{
printf("
分配存储单元失败.\n"
);
//存储单元分配失败
}
S.top=S.base+S.stacksize;
//指明栈顶指针的基址
S.stacksize+=STACKINCREMENT;
//指明栈的空间大小
}
*S.top++=ch;
//先将e送入栈顶指针所指向的单元,再将栈顶指针加
return(OK);
intpop(SqStack&
S,char&
ch)
{//栈顶元素出栈
if(S.top==S.base)
printf("
溢出"
return(ERROR);
ch=*--S.top;
chargettop(SqStackS)
{//返回栈顶元素
if(S.top==S.base)cout<
<
"
栈空,出错"
endl;
chare;
e=*(S.top-1);
returne;
voidprintstack(SqStack&
S,intnaa,intty,ofstream&
fout)
{//输出栈当前情况
chartemp[40][20];
for(intk=0;
k<
40;
k++)
for(intt=0;
t<
20;
t++)
temp[k][t]=NULL;
}
intte=0;
inti=0,j=0;
intnu=0;
char*ku;
ku=S.base;
i=naa+1;
char*contrl;
contrl=S.base;
while(contrl!
=S.top)
if(*contrl!
='
1'
if(*contrl=='
i'
{fout<
if"
;
nu=nu+2;
elseif(*contrl=='
t'
then"
nu=nu+4;
e'
else"
else
*contrl;
nu++;
}
contrl++;
fout<
\t\t\t"
for(i;
i<
=length;
i++)
if(gettop(S)=='
S'
fout<
#"
else
attname[i].select;
if(gettop(S)=='
fout<
else
temp[te];
te++;
(2)其他
intgetnum(charcc)
{//返回元素在优先表中的位置
switch(cc)
case'
:
return0;
break;
return1;
E'
return2;
return3;
B'
return4;
return5;
('
return6;
)'
return7;
'
return8;
return9;
return10;
A'
return11;
d'
return12;
n'
return13;
C'
return14;
{'
return15;
}'
return16;
+'
return17;
-'
return18;
*'
return19;
/'
return20;
#'
return21;
default:
return88;
intjudge(char*string)
{//判断是否是关键字
char*keywords[1000]={"
"
for(inti=0;
i<
=2;
i++)
if(!
strcmp(string,*(keywords+i)))
return1;
return0;
6.5主程序
主程序主要负责,用户界面的初始化,以及程序执行控制。
程序如下:
intmain()
inttest=0;
cout<
==============================================================================="
cout<
=IF-ELSE条件语句的翻译程序设计(简单优先法、输出四元式)="
charinFile[100],wordOutFile[100],stackFile[100];
ifstream*fin;
ofstream*wordOut,*stackOut;
while(true)
输入源文件名(包括路径):
cin>
inFile;
fin=newifstream(inFile);
if(fin==NULL)
输入源文件名错误!
\n"
continue;
break;
输入单词输出文件(包括路径):
wordOutFile;
wordOut=newofstream(wordOutFile);
if(wordOut==NULL)
输入文件名错误!
输入栈情况输出文件(包括路径):
stackFile;
stackOut=newofstream(stackFile);
if(stackOut==NULL)
getchar();
test=analysis(*fin,*wordOut);
if(test==1)
test=laynax(*stackOut);
printfou();
7测试方法和结果
7.1测试方法
(1)程序设计过程中采用单步测试的方法,每完成一个独立的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课程设计 IFELSE 条件 语句 翻译 程序设计