




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、编译原理 编译器综合实验-工程精品 神刀公子一 实验背景编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程序。一个现代编译器的主要工作流程:源代码 (source code) 预处理器 (preprocessor) 编译器 (compiler) 目标代码 (object code) 链接器(Linker) 可执行程序 (executables)高级计算机语言便于人编写,阅读交流,维护。机器语言是计算机能直接解读、运行的。编译器将汇编或高级计算机语言源程序(Sour
2、ce program)作为输入,翻译成目标语言(Target language)机器代码的等价程序。源代码一般为高级语言 (High-level language), 如Pascal、C、C+、Java、汉语编程等或汇编语言,而目标则是机器语言的目标代码(Object code),有时也称作机器代码(Machine code)。对于C#、VB等高级语言而言,此时编译器完成的功能是把源码(SourceCode)编译成通用中间语言(MSIL/CIL)的字节码(ByteCode)。最后运行的时候通过通用语言运行库的转换,编程最终可以被CPU直接计算的机器码(NativeCode)。二 算法设计典型的
3、编译器输出是由包含入口点的名字和地址, 以及外部调用(到不在这个目标文件中的函数调用)的机器代码所组成的目标文件。一组目标文件,不必是同一编译器产生,但使用的编译器必需采用同样的输出格式,可以链接在一起并生成可以由用户直接执行的EXE,词法分析程序 à 语法分析程序 à 语义分析程序 à编译器。不断完善,不断改进。渐变的过程。函数。void scanner(); /扫描void lrparser(); void staBlock(int *nChain); /语句块void staString(int *nChain); /语句串void sta(int *nCh
4、ain); /语句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和p2void emit(char *res,char *num1,char *op,char *num2); /生成四元式截图说明:
5、综合输入:(赋值,循环,条件。结合,自己定义即可)源代码:/*编译器*/*Erin*/*软件工程0801班*/*HUST*/*#include<stdio.h>#include<string.h>#include<math.h>#include<stdlib.h>char prog80; /存放所有输入字符 char token8; /存放词组 char ch; /单个字符 int syn,p,m,n,i; /syn:种别编码 double sum; int count; int isSignal; /是否带正负号(0不带,1负号,2正号)int
6、 isError;int isDecimal; /是否是小数 double decimal; /小数 int isExp; /是否是指数 int index; /指数幂 int isNegative; /是否带负号 double temp; int temp2;int repeat; /是否连续出现+,-int nextq;int kk; /临时变量的标号int ntc,nfc,nnc,nnb,nna;char *rwtab9="main","int","float","double","char&quo
7、t;,"if","else","do","while" structchar result10; /字符串(字符数组)char arg110;char opera10;char arg210;fourCom20; /结构体数组void scanner(); /扫描void lrparser(); void staBlock(int *nChain); /语句块void staString(int *nChain); /语句串void sta(int *nChain); /语句void fuzhi(); /赋值语句v
8、oid 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和p2void emit(char *res,char *num1,char *op,char *num2); /生成四元式void main()p=0;count=0;isDecimal=0
9、;index=0;repeat=0;kk=0;printf("nPlease input your source string:n");doch=getchar();progp+=ch;while(ch!='#');p=0;isError=0;scanner();lrparser();for(i=1;i<nextq;i+) /循环输出四元式printf("n%dt",i);printf("(%5s %5s %5s t%5s )n",fourComi.arg1,fourComi.opera,fourComi.arg
10、2,fourComi.result);void lrparser()int nChain;nfc=ntc=1;nextq=1;if(syn=1) /mainscanner();if(syn=26) /(scanner();if(syn=27) /)scanner();staBlock(&nChain);elseprintf("缺少右括号n");else printf("缺少左括号n");elseprintf("缺少mainn");/<语句块> := ''<语句串>''vo
11、id staBlock(int *nChain) /语句块if(syn=28) /scanner();staString(nChain);/backpatch(*nChain,nextq);if(syn=29) /scanner(); /读下一个elseprintf("缺少号n");elseprintf("缺少号n");/<语句串>:=<语句><语句>void staString(int *nChain) /语句串sta(nChain);backpatch(*nChain,nextq);while(syn=31) /;
12、scanner();sta(nChain);/backpatch(*nChain,nextq-1);void sta(int *nChain) /语句if(syn=10)fuzhi();/*nChain=0;else if(syn=6) /iftiaojian(nChain);else if(syn=8) /doxunhuan();/<条件语句>->if(<条件>)<语句块>void tiaojian(int *nChain)char res10,num110,num210,op10;int nChainTemp;/<条件>-><
13、;表达式><关系运算符><表达式>if(syn=6) /ifscanner();/strcpy(num1,E();if(syn=26) /(scanner();strcpy(num1,E();if(syn<=37)&&(syn>=32) switch(syn)case 32:strcpy(op,">");break;case 33:strcpy(op,">=");break;case 34:strcpy(op,"<");break;case 35:strcpy
14、(op,"<=");break;case 36:strcpy(op,"=");break;case 37:strcpy(op,"!=");break;default:printf("error");scanner();strcpy(num2,E();strcat(num1,op);strcat(num1,num2);/nfc=nextq+1;ntc=nextq; /记住if语句位置emit("0","if",num1,"goto"); nfc=nex
15、tq; /if中表达式为假emit("0","","","goto");/第一个0已回填backpatch(ntc,nextq); /ntc链接的所有四元式都回填nextqif(syn=27) /)scanner();staBlock(&nChainTemp); /语句块*nChain=merge(nChainTemp,nfc);/<循环语句>:=do <语句块>while <条件>void xunhuan()char res10,num110,num210,op10;i
16、nt nChainTemp;if(syn=8) /donnc=nextq; /记住if语句位置,emit之后nextq就变了/emit("0","if",num1,"goto"); scanner();staBlock(&nChainTemp); /语句块if(syn=9) /whilescanner();if(syn=26) /(scanner();strcpy(num1,E();if(syn<=37)&&(syn>=32) switch(syn)case 32:strcpy(op,"&
17、gt;");break;case 33:strcpy(op,">=");break;case 34:strcpy(op,"<");break;case 35:strcpy(op,"<=");break;case 36:strcpy(op,"=");break;case 37:strcpy(op,"!=");break;default:printf("error");scanner();strcpy(num2,E();strcat(num1,op);
18、strcat(num1,num2);nnb=nextq;emit("0","if",num1,"goto"); backpatch(nnb,nnc);nna=nextq;emit("0","","","goto");backpatch(nna,nextq);if(syn=27) /)scanner();void fuzhi() /赋值语句只有1个操作数char res10,num10; /num操作数if(syn=10) /字符串strcpy(res,to
19、ken); /结果scanner();if(syn=21) /=scanner();strcpy(num,E();emit(res,num,"=","");elseprintf("缺少=号n");char* E() /Expression表达式char *res,*num1,*op,*num2;res=(char *)malloc(10);num1=(char *)malloc(10);op=(char *)malloc(10);num2=(char *)malloc(10);strcpy(num1,T();while(syn=22)
20、|(syn=23) /+ -if(syn=22) /+strcpy(op,"+");elsestrcpy(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=(cha
21、r *)malloc(10);strcpy(num1,F();while(syn=24)|(syn=25) /* /if(syn=24) strcpy(op,"*");elsestrcpy(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,
22、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;elseisError=1;return res;char *newTemp()char *p;char varTemp10;p=(char *)malloc(10);kk+;itoa(kk,varTemp,10);strcpy(p+1,varTemp);p0='T'retur
23、n p;/将p所链接的每个四元式的第四个分量都回填tvoid backpatch(int p,int t) int w,circle=p;while(circle) /circle不为0的时候w=atoi(fourComcircle.result); /四元式circle第四分量内容/strcpy(fourComcircle.result,t); /把t填进四元式circle的第四分量sprintf(fourComcircle.result,"%d",t);circle=w; /w记录的是链条上下一个四元式,移动!return;int merge(int p1,int p2
24、) /合并p1和p2char circle,nResult;if(p2=0)nResult=p1;elsenResult=circle=p2;while(atoi(fourComcircle.result) /四元式第四个分量不为0circle=atoi(fourComcircle.result); /strcpy(fourComcircle.result,p1);sprintf(fourComcircle.result,"%s",p1);/目的是用p1的值覆盖0return nResult; /p2是头,p1覆盖0,接在p2后边void emit(char *res,ch
25、ar *num1,char *op,char *num2)strcpy(fourComnextq.result,res);strcpy(fourComnextq.arg1,num1);strcpy(fourComnextq.opera,op);strcpy(fourComnextq.arg2,num2);nextq+;void scanner() sum=0; decimal=0; m=0; for(n=0;n<8;n+) tokenn=NULL; ch=progp+; /从prog中读出一个字符到ch中 while(ch=' '|ch='n') /跳过空
26、字符(无效输入) ch=progp+; if(ch>='a')&&(ch<='z')|(ch>='A')&&(ch<='Z') /ch是字母字符 while(ch>='a')&&(ch<='z')|(ch>='A')&&(ch<='Z')|(ch>='0')&&(ch<='9') tokenm+=c
27、h; /ch=>token ch=progp+; /读下一个字符 tokenm+='0' p-; /回退一格 syn=10; /标识符 /如果是"begin","if","then","while","do","end"标识符中的一个 for(n=0;n<9;n+) if(strcmp(token,rwtabn)=0) syn=n+1; break; else if(ch>='0')&&(ch<='
28、;9') IsNum: if(isSignal=1) /tokenm+='-' while(ch>='0')&&(ch<='9') sum=sum*10+ch-'0' /ch中数字本身是当做字符存放的 ch=progp+; if(ch='.') isDecimal=1; ch=progp+; count=0; /之前忘了清零,123.123+123.123#两个浮点数就无法识别 while(ch>='0')&&(ch<='9
29、39;) /pow(x,y)计算x的y次幂 temp=(ch-'0')*pow(0.1,+count); decimal=decimal+temp; /AddToDec(); ch=progp+; sum=sum+decimal; if(ch='e'|ch='E') isExp=1; ch=progp+; if(ch='-') isNegative=1; ch=progp+; while(ch>='0')&&(ch<='9') /指数 index=index*10+ch-
30、'0' ch=progp+; /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; tokenm+=ch; ch=progp+; if(ch='=') syn=35; tokenm+=ch; else sy
31、n=34; p-; break; case '>': m=0; tokenm+=ch; ch=progp+; if(ch='=') syn=33; tokenm+=ch; else syn=32; p-; break; case '=': m=0; tokenm+=ch; ch=progp+; if(ch='=') syn=36; tokenm+=ch; else syn=21; p-; break; case '+':temp2=progp;tokenm+=ch;if(temp2>='0')&&(temp2<='9')&&(repeat=1)isSignal=2;ch=progp+;repeat=0;goto IsN
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 第11课《答谢中书书》教学设计-2024-2025学年统编版语文八年级上册
- 5,3细胞呼吸的原理和应用-第一课时教学设计-2024-2025学年高一上学期生物人教版(2019)必修1
- 第八单元《词义的辨析和词语的使用》教学设计 2024-2025学年统编版高中语文必修上册
- 2 回延安2024-2025学年八年级下册语文同步教学设计(统编版)
- Unit 7 Happy birthday Section A Grammar 教学设计2024-2025学年人教版(2024)七年级英语上册
- 第五单元 货币与赋税制度 单元教学设计-2023-2024学年高中历史统编版(2019)选择性必修1
- 2024年12月江苏省医疗器械检验所工作人员6人笔试历年典型考题(历年真题考点)解题思路附带答案详解
- 第3章数据处理与应用3.4数据分析报告与应用 -高中教学同步《信息技术-数据与计算》教学设计(人民教育出版社)
- 2025年湖南都市职业学院单招职业技能测试题库完美版
- 篮球 行进间双手胸前传接球 教学设计-2023-2024学年高一上学期体育与健康人教版必修第一册
- 教师师德和专业发展课件
- 服务器巡检报告模版
- 2023年中国煤化工行业全景图谱
- 2023年高中生物新教材人教版(2023年)必修二全册教案
- 小学美术 四年级 人教版《造型•表现-色彩表现与创作》“色彩”单元美术作业设计《色彩的明与暗》《色彩的渐变》《色彩的情感》
- 中国心脏重症镇静镇痛专家共识专家讲座
- 川教版七年级生命生态安全下册第1课《森林草原火灾的危害》教案
- 护理人员心理健康
- 安全技术说明书粗苯
- 单招面试技巧范文
- 情报信息收集报知
评论
0/150
提交评论