编译原理实验 编译器 综合报告(附源代码)_编译原理实验报告模版

2020-02-27 其他范文 下载本文

编译原理实验 编译器 综合报告(附源代码)由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“编译原理实验报告模版”。

编译原理 编译器综合实验

---------------工程精品

神刀公子

一. 实验背景

编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程序。一个现代编译器的主要工作流程:源代码(source code)→ 预处理器(preproceor)→ 编译器(compiler)→ 目标代码(object code)→ 链接器(Linker)→ 可执行程序(executables)高级计算机语言便于人编写,阅读交流,维护。机器语言是计算机能直接解读、运行的。编译器将汇编或高级计算机语言源程序(Source program)作为输入,翻译成目标语言(Target language)机器代码的等价程序。源代码一般为高级语言(High-level language),如Pascal、C、C++、Java、汉语编程等或汇编语言,而目标则是机器语言的目标代码(Object code),有时也称作机器代码(Machine code)。

对于C#、VB等高级语言而言,此时编译器完成的功能是把源码(SourceCode)编译成通用中间语言(MSIL/CIL)的字节码(ByteCode)。最后运行的时候通过通用语言运行库的转换,编程最终可以被CPU直接计算的机器码(NativeCode)。

二. 算法设计

典型的编译器输出是由包含入口点的名字和地址,以及外部调用(到不在这个目标文件中的函数调用)的机器代码所组成的目标文件。一组目标文件,不必是同一编译器产生,但使用的编译器必需采用同样的输出格式,可以链接在一起并生成可以由用户直接执行的EXE, 词法分析程序  语法分析程序  语义分析程序 编译器。不断完善,不断改进。渐变的过程。

。。函数。。

void scanner();//扫描 void lrparser();

void staBlock(int *nChain);//语句块 void staString(int *nChain);//语句串 void sta(int *nChain);//语句 void fuzhi();//赋值语句

void tiaojian(int *nChain);//条件语句 void xunhuan();//循环语句 char* E();//Expresiion表达式 char* T();//Term项 char* F();//Factor因子

char *newTemp();//自动生成临时变量 void backpatch(int p,int t);//回填

int merge(int p1,int p2);//合并p1和p2 void emit(char *res,char *num1,char *op,char *num2);//生成四元式

截图说明:

综合输入:(赋值,循环,条件。。结合,自己定义即可)

源代码:

//************编译器******************** // //***Erin*** //***软件工程0801班*** //***HUST*** // //**************************************

#include #include #include #include

char prog[80];//存放所有输入字符

char token[8];//存放词组

char ch;//单个字符

int syn,p,m,n,i;//syn:种别编码

double sum;

int count;

int isSignal;//是否带正负号(0不带,1负号,2正号)int isError;int isDecimal;//是否是小数

double decimal;//小数

int isExp;//是否是指数

int index;//指数幂

int isNegative;//是否带负号

double temp;

int temp2;

int repeat;//是否连续出现+,{

if(syn==22)//+

strcpy(op,“+”);

else

strcpy(op,“-”);

scanner();

strcpy(num2,T());

strcpy(res,newTemp());

emit(res,num1,op,num2);

strcpy(num1,res);} return num1;}

char* T()//Term项 { char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)malloc(10);num2=(char *)malloc(10);strcpy(num1,F());while((syn==24)||(syn==25))//* / {

if(syn==24)

strcpy(op,“*”);

else

strcpy(op,“/”);

scanner();

strcpy(num2,F());

strcpy(res,newTemp());

emit(res,num1,op,num2);

strcpy(num1,res);} return num1;}

char* F()//Factor因子 { char *res;

res=(char *)malloc(10);if(syn==10)//字符串 { strcpy(res,token);scanner();} else if(syn==20)//二进制数 {

itoa((int)sum,res,10);//整数转换为字符串

scanner();} else if(syn==26)//({

scanner();

res=E();

if(syn==27)//)

{

scanner();

}

else isError=1;} else

isError=1;return res;}

char *newTemp(){ char *p;char varTemp[10];p=(char *)malloc(10);kk++;itoa(kk,varTemp,10);strcpy(p+1,varTemp);p[0]='T';return p;}

//将p所链接的每个四元式的第四个分量都回填t void backpatch(int p,int t){ int w,circle=p;while(circle)//circle不为0的时候

{

} w=atoi(fourCom[circle].result);//四元式circle第四分量内容

//strcpy(fourCom[circle].result,t);//把t填进四元式circle的第四分量

sprintf(fourCom[circle].result,“%d”,t);circle=w;//w记录的是链条上下一个四元式,移动!} return;int merge(int p1,int p2)//合并p1和p2 { char circle,nResult;if(p2==0)

nResult=p1;else {

nResult=circle=p2;

} while(atoi(fourCom[circle].result))//四元式第四个分量不为0 { circle=atoi(fourCom[circle].result);

//strcpy(fourCom[circle].result,p1);sprintf(fourCom[circle].result,“%s”,p1);} //目的是用p1的值覆盖0 return nResult;//p2是头,p1覆盖0,接在p2后边 }

void emit(char *res,char *num1,char *op,char *num2){ strcpy(fourCom[nextq].result,res);strcpy(fourCom[nextq].arg1,num1);strcpy(fourCom[nextq].opera,op);strcpy(fourCom[nextq].arg2,num2);nextq++;}

void scanner()

{

sum=0;

decimal=0;

m=0;

for(n=0;n

token[n]=NULL;

ch=prog[p++];//从prog中读出一个字符到ch中

while(ch==' '||ch=='n')//跳过空字符(无效输入)

ch=prog[p++];

if(((ch>='a')&&(ch='A')&&(ch

{

while(((ch>='a')&&(ch='A')&&(ch='0')&&(ch

{

token[m++]=ch;//ch=>token

ch=prog[p++];//读下一个字符

}

token[m++]='';

p--;//回退一格

syn=10;//标识符

//如果是“begin”,“if”,“then”,“while”,“do”,“end”标识符中的一个

for(n=0;n

if(strcmp(token,rwtab[n])==0)

{

syn=n+1;

break;

}

}

else if((ch>='0')&&(ch

{

IsNum:

if(isSignal==1)

{

//token[m++]='-';

}

while((ch>='0')&&(ch

{

sum=sum*10+ch-'0';//ch中数字本身是当做字符存放的ch=prog[p++];

}

if(ch=='.')

{

isDecimal=1;

ch=prog[p++];

count=0;//之前忘了清零,123.123+123.123#两个浮点数就无法识别

while((ch>='0')&&(ch

{

//pow(x,y)计算x的y次幂

temp=(ch-'0')*pow(0.1,++count);

decimal=decimal+temp;

//AddToDec();

ch=prog[p++];

}

sum=sum+decimal;

}

if(ch=='e'||ch=='E')

{

isExp=1;

ch=prog[p++];

if(ch=='-')

{

isNegative=1;

ch=prog[p++];

}

while((ch>='0')&&(ch

{

//指数

index=index*10+ch-'0';

ch=prog[p++];

}

//10的幂

//123e3代表123*10(3)

//sum=sum*pow(10,index);是错误的if(isNegative)

sum=sum*pow(0.1,index);

else

sum=sum*pow(10,index);

}

if(isSignal==1)

{

sum=-sum;

isSignal=0;

}

p--;

syn=20;

}

else switch(ch)

{

case '

m=0;

token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{

syn=35;

token[m++]=ch;

}

else

{

syn=34;

p--;

}

break;

case '>':

m=0;

token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{

syn=33;

token[m++]=ch;

}

else

{

syn=32;

p--;

}

break;

case '=':

m=0;

token[m++]=ch;

ch=prog[p++];

if(ch=='=')

{

syn=36;

token[m++]=ch;

}

else

{

syn=21;

p--;

}

break;

case '+':

temp2=prog[p];

token[m++]=ch;

if((temp2>='0')&&(temp2

{

isSignal=2;

ch=prog[p++];

repeat=0;

goto IsNum;

}

if(((temp2=='+')||(temp2=='-'))&&(repeat==0))的+,-视为正负号

{

repeat=1;

//ch=prog[p++];

}

syn=22;

break;

case '-':

temp2=prog[p];

token[m++]=ch;

if((temp2>='0')&&(temp2

{

isSignal=1;

ch=prog[p++];//读“-”下一个字符

repeat=0;

goto IsNum;//转到数字的识别

}

if(((temp2=='+')||(temp2=='-'))&&(repeat==0))的+,-视为正负号

{

repeat=1;//预言会重复

//如果重复出现符号,才将后边//如果重复出现符号,才将后边

//ch=prog[p++];//读下一个字符

}

syn=23;

break;

case '*':

temp2=prog[p];

token[m++]=ch;

if(temp2=='+')

{

isSignal=2;

repeat=1;

}

else if(temp2=='-')

{

isSignal=1;

repeat=1;

}

syn=24;

break;

case '/':

syn=25;

token[m++]=ch;

break;

case '(':

temp2=prog[p];

token[m++]=ch;

if(temp2=='+')

{

isSignal=2;

repeat=1;

}

else if(temp2=='-')

{

isSignal=1;

repeat=1;

}

syn=26;

break;

case ')':

syn=27;

token[m++]=ch;

break;

case '{':

syn=28;

token[m++]=ch;

break;

case '}':

syn=29;

token[m++]=ch;

break;

case ',':

syn=30;

token[m++]=ch;

break;

case ';':

syn=31;

token[m++]=ch;

break;

case'#':

syn=0;

token[m++]=ch;

break;

default:

syn=-1;

}

}

《编译原理实验 编译器 综合报告(附源代码).docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
编译原理实验 编译器 综合报告(附源代码)
点击下载文档
相关专题 编译原理实验报告模版 报告 综合 编译器 编译原理实验报告模版 报告 综合 编译器
[其他范文]相关推荐
    [其他范文]热门文章
      下载全文