编译原理课程设计IFELSE条件语句的翻译程序设计.docx

上传人:b****5 文档编号:6823196 上传时间:2023-01-10 格式:DOCX 页数:20 大小:95.83KB
下载 相关 举报
编译原理课程设计IFELSE条件语句的翻译程序设计.docx_第1页
第1页 / 共20页
编译原理课程设计IFELSE条件语句的翻译程序设计.docx_第2页
第2页 / 共20页
编译原理课程设计IFELSE条件语句的翻译程序设计.docx_第3页
第3页 / 共20页
编译原理课程设计IFELSE条件语句的翻译程序设计.docx_第4页
第4页 / 共20页
编译原理课程设计IFELSE条件语句的翻译程序设计.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

编译原理课程设计IFELSE条件语句的翻译程序设计.docx

《编译原理课程设计IFELSE条件语句的翻译程序设计.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计IFELSE条件语句的翻译程序设计.docx(20页珍藏版)》请在冰豆网上搜索。

编译原理课程设计IFELSE条件语句的翻译程序设计.docx

编译原理课程设计IFELSE条件语句的翻译程序设计

课程设计任务书

学生姓名:

_____专业班级:

指导教师:

_工作单位:

计算机科学与技术学院

题目:

IF-ELSE条件语句的翻译程序设计(简单优先法、输出四元式)

初始条件:

理论:

学完编译课程,掌握一种计算机高级语言的使用。

实践:

计算机实验室提供计算机及软件环境。

如果自己有计算机可以在其上进行设计。

要求完成的主要任务:

(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)

(1)写出符合给定的语法分析方法的文法及属性文法。

(2)完成题目要求的中间代码四元式的描述。

(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。

(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

(5)设计报告格式按附件要求书写。

课程设计报告书正文的内容应包括:

1系统描述(问题域描述);

2文法及属性文法的描述;

3语法分析方法描述及语法分析表设计;

4按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;

5编译系统的概要设计;

6详细的算法描述(流程图或伪代码);

7软件的测试方法和测试结果;

8研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);

9参考文献(按公开发表的规范书写)。

时间安排:

设计安排一周:

周1、周2:

完成系统分析及设计。

周3、周4:

完成程序调试及测试。

周5:

撰写课程设计报告。

设计验收安排:

设计周的星期五第1节课开始到实验室进行上机验收。

设计报告书收取时间:

设计周的次周星期一上午10点。

指导教师签名:

2012年10月23日

系主任(或责任教师)签名:

2012年10月23日

IF-ELSE条件语句的翻译程序设计

(简单优先法、输出四元式)

1系统描述

1.1实验目的

对条件语句:

IF<布尔表达式>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

(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

(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

当文法中存在A->…XB…时,X

当文法中存在A->…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,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是数字)

{

ch存入temp;

读取下一个字符;

}

temp入名字表并设置正确的属性。

}

elseif(ch为其他合法字符(如:

>,<,=等等))填入名字表。

else输出错误,无法识别的字符。

}

6.3语法分析

语法分析主要为laynax(ofstream&f)函数,其中,f为栈变化情况输出文件。

其他辅助函数为除judge(char*string)外的其他所有辅助函数。

语法分析的过称描述如下:

初始化分析栈;

while(还有单词)

{

判断当前栈顶单词与输入单词的优先级;

if(<||=)当前符号入栈

elseif(>)

{

while(栈顶元素优先级等于输入单词)

{

保存输入单词;

置输入单词为栈顶单词;

栈顶元素出栈;

}

判断保存单词串是否为句柄;

if(是句柄)

{

进行规约;

进行语义规则计算;

输出栈的变化情况;

使规约后单词为新的输入符号;

}

else

{

输出规约出错;

}

}

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)));

if(!

S.base)

{

printf("分配存储单元失败.\n");//存储单元分配失败

exit(OVERFLOW);

}

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;

return(OK);

}

chargettop(SqStackS)

{//返回栈顶元素

if(S.top==S.base)cout<<"栈空,出错"<

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')

{fout<<"then";nu=nu+4;}

elseif(*contrl=='e')

{fout<<"else";nu=nu+4;}

else

{fout<<*contrl;nu++;}

}

contrl++;

}

fout<<"\t\t\t";

for(i;i<=length;i++)

{

if(gettop(S)=='S')

fout<<"#";

else

fout<

}

if(gettop(S)=='S')

fout<<"#";

else

fout<

te++;

fout<

}

(2)其他

intgetnum(charcc)

{//返回元素在优先表中的位置

switch(cc)

{

case'S':

return0;break;

case'i':

return1;break;

case'E':

return2;break;

case't':

return3;break;

case'B':

return4;break;

case'e':

return5;break;

case'(':

return6;break;

case')':

return7;break;

case'>':

return8;break;

case'<':

return9;break;

case'=':

return10;break;

case'A':

return11;break;

case'd':

return12;break;

case'n':

return13;break;

case'C':

return14;break;

case'{':

return15;break;

case'}':

return16;break;

case'+':

return17;break;

case'-':

return18;break;

case'*':

return19;break;

case'/':

return20;break;

case'#':

return21;break;

default:

return88;

}

}

intjudge(char*string)

{//判断是否是关键字

char*keywords[1000]={"if","then","else"};

for(inti=0;i<=2;i++)

{

if(!

strcmp(string,*(keywords+i)))

{

return1;

}

}

return0;

}

 

6.5主程序

主程序主要负责,用户界面的初始化,以及程序执行控制。

程序如下:

intmain()

{

inttest=0;

cout<<"==============================================================================="<

cout<<"=IF-ELSE条件语句的翻译程序设计(简单优先法、输出四元式)="<

cout<<"==============================================================================="<

charinFile[100],wordOutFile[100],stackFile[100];

ifstream*fin;

ofstream*wordOut,*stackOut;

while(true)

{

printf("输入源文件名(包括路径):

");

cin>>inFile;

fin=newifstream(inFile);

if(fin==NULL)

{

printf("输入源文件名错误!

\n");

continue;

}

break;

}

while(true)

{

printf("输入单词输出文件(包括路径):

");

cin>>wordOutFile;

wordOut=newofstream(wordOutFile);

if(wordOut==NULL)

{

printf("输入文件名错误!

\n");

continue;

}

break;

}

while(true)

{

printf("输入栈情况输出文件(包括路径):

");

cin>>stackFile;

stackOut=newofstream(stackFile);

if(stackOut==NULL)

{

printf("输入文件名错误!

\n");

continue;

}

break;

}

getchar();

test=analysis(*fin,*wordOut);

if(test==1)

{

test=laynax(*stackOut);

}

else

return0;

if(test==1)

{

printfou();

}

return0;

}

7测试方法和结果

7.1测试方法

(1)程序设计过程中采用单步测试的方法,每完成一个独立的

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1