while循环语句的翻译程序设计(简单优先法,三地址输出)
目录
1 问题域描述..........................................3
2 文法及属性文法的描述.........................3
2.1 WHILE循环语句的文法................................3
2.2 WHILE循环语句的属性文法............................4
3 语法分析方法及中间代码形式的描述................4
3.1语法分析方法........................................4
3.2中间代码形式描述....................................6
4 编译系统的概要设计.................................7
4.1词法分析............................................7
4.2语法制导翻译........................................8
5 详细的算法描述.....................................8
5.1 文法设计...........................................8
5.2 算法描述...........................................8
5.3 源程序代码.........................................9
6 软件的调试过程和结果测试.........................19
6.1调试过程............................................19
6.2结果测试............................................19
7 使用说明............................................20
8 课设
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
............................................20
9 参考文献.............................................22
WHILE循环语句的翻译程序设计
(简单优先法、输出三地址
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
示)
1 问题域描述
while循环语句的翻译程序设计(简单优先法,输出单地址表示),要求完成:
(1) 用C++语言正确编写程序,完成WHILE循环语句的翻译程序设计。
(2) 求能正确进行词法分析,语法分析,并能正确的输出预期结果。
(3) 根据指定的文法,判定程序的正确性。
本次课程设计中要求设计一个WHILE循环语句的词法)语法及语义分析程序,语法分析选择简单优先法,采用语法制导翻译输出中间代码三元式。通过设计、编制、调试一个 WHILE循环语句的语法及语义分析程序,加深对语法及语义分析原理的理解,实现功能。
while循环语句的格式为:while(P){do A},其中A为循环体,可为一个或多个赋值语句;P为循环控制条件。while循环语句首先根据循环控制条件P进行判断,若满足条件则执行循环体A,否则执行下面的程序段;
本次课程设计中系统首先要进行词法分析,即从左到右把源文件的字符序列逐个进行扫描,产生一个个的单词序列,作为语法分析的输入从而继续编译过程。
该程序的语法分析读入词法分析的结果,并判断输入语句是否满足while循环语句的文法所描述的形式。通过简单优先法对语句进行分析,看是否能通过给定的输入串归约到文法的开始符号。在语法分析的同时进行语义分析,最后输出三元式的代码。
2 文法及属性文法的描述
2.1WHILE循环语句的文法
定义一个文法,文法G(S)如下:
S-> while(P){A};
A->id=E;
E->TE'
E'->+TE' | -TE' | e
T->FT'
T'->*FT' | /FT' | e
F->(E) | id
P->E rop id
rop-> > | < | >= | <= | != | ==
2.2 WHILE循环语句的属性文法
产生式 语义规则
S?while P{A} S.addr:=newlabel;
E.true:=newlabel; E.false:=S.next;
S1.next:=S.begin; S.code:=gen(S.begin’:’‖E。code‖
gen(E.true’:’) ‖S1.code‖ gen(‘goto’ S.begin)
3 语法分析方法及中间代码形式的描述
3.1语法分析方法
3.1.1简单优先法
简单优先分析法是按照文法符号(终结符和非终结)的优先关系确定句柄的,因此我们首先介绍任意两个文法符号之间的优先关系是怎样确定的,及如何构造优先关系表。
首先定义优先关系的表示:
X=Y 表示X和Y的优先关系相等
X>Y 表示X的优先性比Y的优先性大
X
( b c ) # **/
/* S */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 1 },
/* w/ { N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* h*/ { N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* i/ { N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, -1, N, N },
/* l/ { N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* e */ { N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* E*/ { N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* d*/ { N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* o*/ { N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* { { N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N },
/* A/ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N },
/*}*/ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N },
/* a */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, 0, N, N, N, N, N },
/* = */ { N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N },
/* + */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N },
/* 1 */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N },
/* ; */ { N, N, N, N, N, 1, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* > */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N },
/* ( */ { N, N, N, N, N, N, N, N, N, N, N, 0, -1, N, N, N, N, N, N, N, N, N, N },
/* b */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
N, N, N, 1, N },
/* c */ { N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N,
N, N, N, N, N },
/* ) */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
N, N, N, N, 1 },
/* # */ { -1, -1, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
N, N, N, N, 0 }};
其中N表示的是没有优先关系, -1表示优先级小于,0表示优先级相同,1表示优先级大于
3.2中间代码形式描述
3.2.1三元式
三元式是一种普遍采用的中间代码形式。它由三个部分组成:算符op,第一和第二运算对象ARG1和ARG2。运算对象有时候指用户自己定义的变量。 3.2.2赋值语句的四元式
对c=a+1翻译结果如下
1)(+,a,1)
2),(=, c, (1))
3.2.3 while(a>b)语句翻译
为方便和直观,将while语句翻译为if a> b goto do.addr 4 编译系统的概要设计
本程序开始,需先对输入字符串进行词法分析,将其识别为一个个独立的单词序列,得到的字符单词要和关键字比较,看是否是关键字,根据比较结果进行返回相应的单词类型。单词类型主要包括标识符,关键字,常量,运算符和分界符。在语法分析程序中,根据词法分析得到的结果,进行判断是否是当前需要的单词类型,如果不是就说明输入字符串不能由该文法推导出来;如果是当前需要的类型,就相应得做该单词类型分支程序。根据简单优先法分析的字符串,看是否能得到接受状态。此外,在进行语法分析的同时进行语义分析,审查程序有无语义错误,每个算符是否具有语言规范允许的运算对象,当不符合语言规范时,编译程序应
报告
软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载
错误。在进行了上述的语法分析和语义分析阶段的工作之后,将源文件变成三元式表示。
源程序目录下建立“input.txt”文本文档,在文档中输入while(P),A,格式的WHILE
语句,再通过调用程序中的get_word(string word)函数进行对文本文档中语句的读取操作。
4.1词法分析
词法分析是编译的第一阶段,它的主要任务是从左至右逐个字符地对源程序进行扫描,产生一个单词序列,用于语法分析。
编程中,建立操作数栈和运算符栈,设定运算符优先级。对于读取的字符进行判定,若是运算符,就与栈顶符号比较优先级,高则入栈,否则栈内运算符出栈;若是非运算符,则送入操作数栈。
4.2语法制导翻译
在语法分析过程中,随着分析的步步进展,根据每个产生式所对应的语义子程序(或语义规则描述的语义动作)进行翻译。属性文法的每个符号有属性,所以每个符号入栈时,必须连属性一起入栈,这样,栈符号就由文法符号及存放该符号属性的域所组成。由于属性类型不同,属性域存放的
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
就要根据属性的类型来定。有的可能直接存放属性值,也有的存放的是指向属性值的指针。对于综合属性,其属性域不存放其属性值,而是存放一个指针,指向存贮该属性值的单元。对于继承属性,其属性域直接保存其属性值。继承属性的属性域刚入栈时为空,但是在该栈符号变成栈顶符号之前的某一时刻,它们必须接受相应的属性值,即在成为栈顶时,继承属性的属性域必须有值。
5 详细的算法描述
5.1 文法设计
为顺利完成本次课程设计,实现要求的功能,设计测试文法G(S)如下:
S-> while(P) {A};
A->id=E;
E->TE'
E'->+TE' | -TE' | e
T->FT'
T'->*FT' | /FT' | e
F->(E) | id
P->E rop id
rop-> > | < | >= | <= | != | ==
5.2 算法描述
(1)word_node * word_link(word_node,word_node,string)//给结点赋值,并设置type值。
(2)void get_word(string word)函数设计:从文本文档中读取字符,存入word_array
(3)简单优先子程序如下:
void rop(word_node *&p) //rop-> > | < | >= | <= | != | ==
void F(word_node *&p) //F->(E) | id
void extend_T(word_node *&p) //T'->*FT' | /FT' | e
void T(word_node *&p) //T->FT'
void extend_E(word_node *&p) //E'->+TE' | -TE' | e
void E(word_node *&p) //E->TE'
void P(word_node *&p) //P->E rop b
void A(word_node *&p) //A->id=E;
bool S(word_node *&p) // while(p) {doA};
5.3 源程序如下
#include"Stack.h" //定义栈,便于归约时运用。 #include
#include //文件输入
#include
using namespace std;
#define norw 13 //关键字的个数
#define nmax 14 //数字的最大位数
#define al 10 //符号的最大长度
#define N -10
#define getchdo if(getch()==-1)return -1
#define getsymdo if(getsym()==-1)return -1
ifstream *fin;
SeqStack Sym,Opt,Opr;
char *p,ch;
char str[20];
char inputstr[100]; //保存从文件读入的所有字符 char buf[5][20];
int count1=0,count2=0;
int ip=0,row,line;
enum symbol sym; //当前的符号
int num; //当前number
char a[al+1]; //临时符号
char id[al+1]; //当前ident
char word[norw][al]; //保留字
enum symbol wsym[norw]; //关键字的符号值 enum symbol ssym[256]; //单字符的符号值 enum symbol{
nul, ident, number, plus, minus, times,
slash, oddsym, eql, neq, lss, leq,
gtr, geq, lparen, rparen, lbrace, rbrace,
comma, semicolon, period, becomes, beginsym, endsym,
ifsym, elsesym, whilesym, writesym, readsym, dosym,
callsym, constsym, varsym, procsym ,greater, less
};
void ThreeAddr();
void init()
{
//设置单字符符号
for(int i=0;i<=255;i++)
{
ssym[i]=nul;
}
ssym['+']=plus;
ssym['-']=minus;
ssym['*']=times;
ssym['/']=slash;
ssym['(']=lparen;
ssym[')']=rparen;
ssym['{']=lbrace;
ssym['}']=rbrace;
ssym['=']=eql;
ssym[',']=comma;
ssym['.']=period;
ssym['#']=neq;
ssym[';']=semicolon;
ssym[ > ]=greater;
ssym[ < ]=less;
//设置保留字名字,
strcpy(&(word[0][0]),"begin");
strcpy(&(word[1][0]),"call");
strcpy(&(word[2][0]),"const");
strcpy(&(word[3][0]),"do");
strcpy(&(word[4][0]),"end");
strcpy(&(word[5][0]),"if");
strcpy(&(word[6][0]),"odd");
strcpy(&(word[7][0]),"procedure");
strcpy(&(word[8][0]),"read");
strcpy(&(word[9][0]),"then");
strcpy(&(word[10][0]),"var");
strcpy(&(word[11][0]),"while");
strcpy(&(word[12][0]),"write");
//设置保留字符号
wsym[0]=beginsym;
wsym[1]=callsym;
wsym[2]=constsym;
wsym[3]=dosym;
wsym[4]=endsym;
wsym[5]=ifsym;
wsym[6]=oddsym;
wsym[7]=procsym;
wsym[8]=readsym;
wsym[9]=elsesym;
wsym[10]=varsym;
wsym[11]=whilesym;
wsym[12]=writesym;
}
char rule[12][20]={
"S-> while(E) {do B}/0;
"B->d=C;\0",
"C->A+A\0",
"C->A-A\0",
"C->A*A\0",
"C->A/A\0",
"C->A\0",
"E->A>A\0",
"E->AA==A\0",
"E->A\0",
"A->d\0",}; //文法
int getch()
{
if(fin->get(ch))
{
if(ch!=' ' && ch!=9 && ch!=10)
{
inputstr[ip]=ch;
ip++;
}
cout<='a'&&ch<='z')
{
k=0;
do{
if(k='a'&&ch<='z'||ch>='0'&&ch<='9');
a[k]=0;
strcpy(id,a);
i=0;
j=norw-1;
do{ //搜索当前符号是否为保留字
k=(i+j)/2;
if(strcmp(id,word[k])<=0)
{
j=k-1;
}
if(strcmp(id,word[k])>=0)
{
i=k+1;
}
}while(i<=j);
if(i-1>j)
{
sym=wsym[k];
}
else
{
sym=ident; //搜索失败,则是名字或数字
}
}
else{
if(ch>='0'&&ch<='9') //
检测
工程第三方检测合同工程防雷检测合同植筋拉拔检测方案传感器技术课后答案检测机构通用要求培训
是否为数字
{
k=0;
num=0;
sym=number;
do{
num=num*10+ch-'0';
k++;
getchdo;
}while(ch>='0'&&ch<='9');
k--;
if(k>nmax)
{
cout<<"error:too large number!"<') //检测大于或大于等于符号
{
getchdo;
if(ch=='=')
{
sym=geq;
getchdo;
}
else
{
sym=gtr;
}
}
else
{
sym=ssym[ch];
if(sym!=period)
{
getchdo;
}
}
}
}
}
}
return 0;
}
//优先关系模块
//定义优先关系
int PreTable[23][23] =
{/** S w h i l e E d o { B }a = + 1 ; > ( b c ) # **/
/* S */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 1 },
/* w/ { N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* h*/ { N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* i/ { N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, -1, N, N },
/* l/ { N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* e */ { N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* E*/ { N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* d*/ { N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* o*/ { N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* { { N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N, N, N },
/* A/ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N },
/*}*/ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N },
/* a */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, 0, N, N, N, N, N },
/* = */ { N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N, N, N, N },
/* + */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N, N },
/* 1 */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N, N, N },
/* ; */ { N, N, N, N, N, 1, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N },
/* > */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
N, 0, N, N, N },
/* ( */ { N, N, N, N, N, N, N, N, N, N, N, 0, -1, N, N, N, N, N,
N, N, N, N, N },
/* b */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
N, N, N, 1, N },
/* c */ { N, N, N, N, N, N, N, N, N, N, N, N, N, 0, N, N, N, N,
N, N, N, N, N },
/* ) */ { N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
N, N, N, N, 1 },
/* # */ { -1, -1, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
N, N, N, N, 0 }};
int Compare(char m,char n)//定义矩阵 {
switch (m)
{
case 'S': row=0;break;
case 'w: row=1;break;
case 'h: row=2;break;
row=3;break; case 'i
case 'l: row=4;break;
case 'e: row=5;break;
case 'E: row=6;break;
case 'd: row=7;break;
case 'o row=8;break;
case '{: row=9;break;
case 'A: row=10;break;
case '}: row=11;break;
case 'a': row=12;break;
case '=': row=13;break;
case '+': row=14;break;
case '1': row=15;break;
case ';': row=16;break;
case '>': row=17;break;
case '(': row=18;break;
case 'b': row=19;break;
case 'c': row=20;break;
case ')': row=21;break;
case '#': row=22;break;
default: return -100;break;
}
switch (n)
{
case 'S': line=0;break;
case 'w: line=1;break;
case 'h: line=2;break;
case '{i line=3;break;
case 'l: line=4;break;
case 'e: line=5;break;
case 'E: line=6;break;
case 'd: line=7;break;
case 'o: line=8;break;
case '{: line=9;break;
case 'A: line=10;break;
case '}: line=11;break;
case 'a': line=12;break;
case '=': line=13;break;
case '+': line=14;break;
case '1': line=15;break;
case ';': line=16;break;
case '>': line=17;break;
case '(': line=18;break;
case 'b': line=19;break;
case 'c': line=20;break;
case ')': line=21;break;
case '#': line=22;break;
default: return -100;break;
}
return PreTable[row][line]; }
void Error()//规约不成功 {
cout<<"归约失败,语法有错误!"<=0;j--)
{
if(buf[i][j]>='a'&&buf[i][j]<='z'||buf[i][j]>='A'&&buf[i][j]<='Z'||buf[
i][j]>='0'&&buf[i][j]<='9')
Opr.Push(buf[i][j]);
else
if(buf[i][j]=='+'||buf[i][j]=='-'||buf[i][j]=='*'||buf[i][j]=='/'||buf[i][j]=
='<'||buf[i][j]=='>'||buf[i][j]=='=')
Opt.Push(buf[i][j]);
}
while(!Opr.Empty() && !Opt.Empty())
{
op1=Opr.TopValue();
Opr.Pop(c);
op2=Opr.TopValue();
Opr.Pop(c);
opt=Opt.TopValue();
if(Opt.TopValue()=='=')
cout<')
{
cout<close();
cout<没有定义,导致后边语法分析产生脱节。
6.2结果测果