⑴ 描述一般的编译程序可分为哪些阶段,每个阶段的目的是什么
其目的是保证标识符和常数的正确使用,把必要的信息...综合部分 综合阶段必须根据符号表和中间语言程序产生...目标程序质量,也可以把一个逻辑步骤的工作分为几遍.
⑵ DO-WHILE循环语句的翻译程序设计(递归下降法、输出四元式)
///////////////////////////////////////////////////////////////////
////董超勋的for循环语句翻译 递归下降法 输出三地址码 /////////////
#define MAX 100
#include<iostream.h>
#include<stdio.h>
#include<string.h>
char str[MAX];
char ch;
int turn;
char strToken[MAX];
int kind;
int n=0;//存放strtoken[]元素的个数
struct Word//结构体 存放单词
{
int sort;
char word[MAX];//存放strtoken[]的内容
};
//record[x]=new Word;
Word *record[12];//放所有识别出来的单词,分别存放他们的编号以及字符串,x是其下标
////////////////////词法分析///////////////////////
int buffer()//载入
{
int i=0;
cout<<"输入程序,以“#”作为结束标志。"<<endl;
for(int n=0;n<=MAX;n++)
{
for(;i<=MAX;i++)
{
scanf("%c",&str[i]);
/////////////cin>>str[i]不可用,用C语言读入字符。
if(str[i]=='#')
break;///////如果尾数为识别码#,则表示程序读完,跳出循环.
}
break;
}
return(i);
}
bool IsLetter(char ch)///////////判断是否是字母
{
if(ch>=65&&ch<=90||ch>=97&&ch<=122)
return(true);
else
return(false);
}
bool IsDigit(char ch)//////////判断是否是数字
{
if(ch>=48&&ch<=57)
return(true);
else
return(false);
}
char GetChar(int i)///////读取字符
{
char ch;
ch=str[i];
return(ch);
}
char GetBC(char ch)////判断是不是空格或者换行,如果是,直接读取下一个字符直道不再空白为止
{
if(ch==32||ch==10)
{
turn++;
ch=GetChar(turn);
ch=GetBC(ch);/////////递归实现
return(ch);
}
else
return(ch);
}
void Concat()/////////////连接,即为strtoken[]赋值
{
strToken[n]=ch;
n++;
}
int Reserve()/////以单词为单位查找保留字,是则返回编码,不是则返回0,用来区分标志符和保留字
{
if(strcmp(strToken," DIM\0")==0)///////调用strcmp函数实现,
return(1);
else if(strcmp(strToken,"for\0")==0)
return(2);
else if(strcmp(strToken,"step\0")==0)
return(3);
else if(strcmp(strToken,"until\0")==0)
return(4);
else if(strcmp(strToken,"do\0")==0)
return(5);
else
return(6);
}
void clear()
{
n=0;
}
/////////////*语法递归分析*/////////////////
int A(int * c,int & q)
{
if(c[q++]==3)
{
if(c[q]==7)
{ q++;
return 1;
}
else {cout<<"step右部出错"<<endl;return 0;}
}else {cout<<"error 'step'"<<endl;return 0;}
}
int B(int * b,int & o)
{
if(b[o++]==4)
{
if(b[o]==7)
{ o++;
return 1;
}
else {cout<<"until右部出错"<<endl;return 0;}
}else {cout<<"error 'until'"<<endl;return 0;}
}
int S2(int * d,int & h)
{
if(d[h++]==6)
{
if(d[h++]==8)
{
if((d[h]==6||d[h]==7)) {h++; return 1;}
else {cout<<"赋值语句右部出错 "<<endl;return 0;}
}else {cout<<"赋值语句缺少赋值运算符 "<<endl;return 0;}
}else {cout<<"赋值语句左部出错 "<<endl;return 0;}
}
int S1(int * m,int & n)
{
if(S2(m,n))
{
if(A(m,n))
{
if(B(m,n)) return 1;
else return 0;
}else return 0;
}else return 0;
}
int S(int *a,int & z)
{
if (a[z++]==2)
{
if (S1(a,z))
{
if(a[z++]==5)
{
if(S2(a,z))
{
cout<<"succeed!"<<endl;return 1;
}else return 0;
}else {cout<<"error 'do'"<<endl; return 0;}
}else return 0;
}else {cout<<"error 'for'"<<endl; return 0;}
}
void main()
{
cout<<"*************产生式***************"<<endl;// for step until do i j =
cout<<" S ->for S1 do S2"<<endl; // 编号 2 3 4 5 6 7 8
cout<<" S1 ->S2AB"<<endl;
cout<<" S2 ->i=j"<<endl;
cout<<" A ->stepj"<<endl;
cout<<" B ->untilj"<<endl;
int num;
turn=0;
num=buffer()-1;
int x=0;//计识别的单词的个数
for(;turn<=num;turn++)//总循环,ch存放刚读入的字符,strtoken[]存放已识别的标志付或保留字,turn是数组str[]的下标
{
ch=GetChar(turn);
ch=GetBC(ch);
if(IsLetter(ch))
{
while(IsLetter(ch)&&turn<=num||IsDigit(ch)&&turn<=num)
{
Concat();
ch=GetChar(++turn);
}
strToken[n]='\0';
ch=NULL;//此ch不是标志符中的符号
turn=turn-1;
kind=Reserve();
record[x]=new Word; record[x]->sort=kind;//12345或6
//cout<<kind; //测试
cout<<"(";
for(int i=0;i<n;i++)
{
record[x]->word[i]=strToken[i];
cout<<record[x]->word[i];//输出识别的标志符或保留字
}
cout<<","<<kind<<")"<<endl;
record[x]->word[i]='\0';
clear();
x++;
}
else if(IsDigit(ch))
{
while(IsDigit(ch)&&turn<=num)
{
Concat();
ch=GetChar(++turn);
}
ch=NULL;
turn=turn-1;
kind=7;
//////////////
record[x]=new Word;
record[x]->sort=kind;
////////////////
cout<<"(";
for(int i=0;i<n;i++)
{
record[x]->word[i]=strToken[i];
cout<<record[x]->word[i];
}
cout<<","<<kind<<")"<<endl;
record[x]->word[i]='\0';
clear();x++;
}
else if(ch=='=')
{
kind=8;
///////
record[x]=new Word;
record[x]->word[0]='=';
record[x++]->sort=kind;
cout<<"(=,"<<kind<<")"<<endl;
}
else
cout<<"error input!"<<endl;
}
//////////////////////*语法分析*////////////////
//int y;
/*for(y=0;y<x;y++)
{cout<<record[y]->sort<<" ";//打印单词的编号 。
}cout<<endl;*/
int ana[MAX];//存放词法分析得到的单词序列的编号的序列
int m;
for(m=0;m<x;m++)
{
ana[m]=record[m]->sort;//将sort作为数组保存起来
}
/////////语法分析///////
int j=0;
///////////////////制导翻译//////////////////
if(!S(ana,j)) cout<<"语法出错!"<<endl;
else
{ cout<<"三地址码如下:"<<endl;
cout<<"100 ";
int i=0;
while(record[1]->word[i]!='\0')
cout<<record[1]->word[i++];cout<<record[2]->word[0];
i=0;
while(record[3]->word[i]!='\0')
cout<<record[3]->word[i++];cout<<endl;
cout<<"101 goto 103"<<endl;
cout<<"102 ";
i=0;
while(record[1]->word[i]!='\0')
cout<<record[1]->word[i++];cout<<":=";
i=0;
while(record[1]->word[i]!='\0')
cout<<record[1]->word[i++];cout<<"+";
i=0;
while(record[5]->word[i]!='\0')
cout<<record[5]->word[i++];cout<<endl;
cout<<"103 if ";
i=0;
while(record[1]->word[i]!='\0')
cout<<record[1]->word[i++];cout<<"<";
i=0;
while(record[7]->word[i]!='\0')
cout<<record[7]->word[i++];
cout<<" goto 105"<<endl;
cout<<"104 goto 107"<<endl;
cout<<"105 ";
i=0;
while(record[9]->word[i]!='\0')
cout<<record[9]->word[i++];cout<<":=";
i=0;
while(record[11]->word[i]!='\0')
cout<<record[11]->word[i++];cout<<endl;
cout<<"106 goto 102"<<endl;
cout<<"107 end"<<endl;
}
}
⑶ 谁有条件语句,while循环语句的四元式生成
所谓四元式是一种表示中间代码的方式,跟三元式、波兰式、逆波兰式的目的是一样的,但四元式在表示简单赋值语句方面非常直观明了,四元式的格式: (操作符,第一操作数,第二操作数,保存结果的变量) 例如:k:=k+1 四元式写成:(+,k,1,k) 如果表达式右边只有单操作数,那就相应位置无值,如: k:=+1 四元式为:(+,-,1,k) 遇到逻辑条件表达式就要分别给出条件为真时的转移路径和条件为假时的转移路径,如: if k>1 四元式为:(j>,k,1,?) ,表示条件为真的时候要转移到的地址“?” (j,-,-,?),表示条件为假时无条件转移到这个地址“?” “?”表示的地址可以用地址回填的方法确定 假设起始地址是100 begin 100:(+,-,100,k) 101:(+,i,j,t1) 102:(j>,k,t1,104) 103:(j,-,-,106) 104:(-,k,1,k) 105:(j,-,-,102) 106:(*,i,i,t2) 107:(*,j,j,t3) 108:(-,t2,t3,k) 109:(+,-,0,i) 110:(+,-,0,j) end
⑷ 编译原理四元式
四元式的一般形式为(op, arg1, arg2, result),其中:op为一个二元(也可以是零元或一元)运算符。arg1和arg2为两个运算对象,可以是变量、常数或者系统定义的临时变量名。result为运算结果。
第一步:T1=a*b,
第二步:T2=c*d,
第三步:T3=T2/e,
第四步:T4=T1-T3,
第五步:f=T4.
⑸ 写出下面语句产生的四元式序列,求答案,谢谢了!
Dim x As Integer If x Then print x Else Print x+1
⑹ 编译原理用C++生成四元式的程序,如果把生成四元式当成一个类来写,那这个类应该有哪些函数
四元式的四个组成成分是:算符op,第一和第二运算对象ARG1和ARG@及运算结果RESULT。
你所有的事情也都是围绕这四个东东来做呀,间接地就是生成“三地址指令”或是转换成“语句”(例如 if B rop C goto L)之类的。
⑺ 编译原理 四元式
四元式是一种比较普遍采用的中间代码形式。
代码段的四元式表达式:
101 T:=0 (表达式为假的出口)
103 T:=1 (表达式为真的出口)
因为用户的表达式只有一个A<B,因此A<B的真假出口就是表达式的真假出口,所以
100: if a<b goto 103 (a<b为真,跳到真出口103)
101: T:=0(否则,进入假出口)
102: goto 104 (要跳过真出口,否则T的值不就又进入真出口了,为真)
103: T:=1
104:(程序继续执行)
(7)四元式是哪个阶段的输出数据扩展阅读:
四元式是一种更接近目标代码的中间代码形式。由于这种形式的中间代码便于优化处理,因此,在目前许多编译程序中得到了广泛的应用。
四元式实际上是一种“三地址语句”的等价表示。它的一般形式为:
(op,arg1,arg2,result)
其中, op为一个二元 (也可是一元或零元)运算符;arg1,arg2分别为它的两个运算 (或操作)对象,它们可以是变量、常数或系统定义的临时变量名;运算的结果将放入result中。四元式还可写为类似于PASCAL语言赋值语句的形式:
result ∶= arg1 op arg2
需要指出的是,每个四元式只能有一个运算符,所以,一个复杂的表达式须由多个四元式构成的序列来表示。例如,表达式A+B*C可写为序列
T1∶=B*C
T2∶=A+T1
其中,T1,T2是编译系统所产生的临时变量名。当op为一元、零元运算符 (如无条件转移)时,arg2甚至arg1应缺省,即result∶=op arg1或 op result ;对应的一般形式为:
(op,arg1,,result)
或
(op,,,result)
⑻ 编译原理中 关于四元式序列 的题~~~!
(1)if a<b goto (7) /* (7)是整个布尔表达式的真出口 */
(2) goto (3)
(3) if c<d goto (5)
(4) goto (p+1) /* (p+1)是整个布尔表达式的假出口 */
(5) if e>f goto (7)
(6) goto (p+1)
⑼ 完成赋值语句,条件语句和WHILE循环语句的四元式生产程序构造,测试用例要求不少于3
改了个JAVA上的事例,输入0-5的数字,然后加1输出的程序,应该能满足你的要求。 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class te...st_01 { public static void main (String args[]) throws IOException{ BufferedReader buf = null; buf = new BufferedReader(new InputStreamReader(System.in)); String str = null; while (true){ { System.out.print("请输入数字:"); try { str = buf.readLine(); } catch (IOException e) { e.printStackTrace(); } int i = -1; try { i = Integer.parseInt(str); if (i>5 |i
⑽ 跪求!我们的作业。 题目:将布尔表达式转换成四元式的程序实现
我自到