编译技术课设 实验报告

合集下载

编译技术实验报告词法(3篇)

编译技术实验报告词法(3篇)

第1篇一、实验目的本次实验旨在通过实践加深对编译技术中词法分析阶段的理解,掌握词法分析的基本原理和方法,能够实现一个简单的词法分析器,并对源代码进行初步的符号化处理。

二、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:Eclipse IDE4. 实验素材:实验提供的C语言源代码三、实验原理词法分析是编译过程中的第一个阶段,其主要任务是将源代码中的字符序列转换成一系列的词法单元(Token)。

词法单元是构成源程序的基本单位,如标识符、关键字、运算符等。

词法分析的基本原理如下:1. 字符流:从源代码中逐个读取字符,形成字符流。

2. 状态转换:根据字符流中的字符,在有限状态自动机(FSM)中转换状态。

3. 词法单元生成:当状态转换完成后,生成对应的词法单元。

4. 错误处理:在分析过程中,如果遇到无法识别的字符或状态,进行错误处理。

四、实验步骤1. 设计词法分析器:根据C语言的语法规则,设计有限状态自动机,定义状态转换图。

2. 实现状态转换函数:根据状态转换图,实现状态转换函数,用于将字符流转换为词法单元。

3. 实现词法单元生成函数:根据状态转换结果,生成对应的词法单元。

4. 测试词法分析器:使用实验提供的C语言源代码,测试词法分析器的正确性。

五、实验结果与分析1. 词法分析器设计:根据C语言的语法规则,设计了一个包含26个状态的状态转换图。

状态转换图包括以下状态:- 初始状态:用于开始分析。

- 标识符状态:用于分析标识符。

- 关键字状态:用于分析关键字。

- 运算符状态:用于分析运算符。

- 数字状态:用于分析数字。

- 字符串状态:用于分析字符串。

- 错误状态:用于处理非法字符。

2. 状态转换函数实现:根据状态转换图,实现了状态转换函数。

该函数用于将字符流转换为词法单元。

3. 词法单元生成函数实现:根据状态转换结果,实现了词法单元生成函数。

该函数用于生成对应的词法单元。

编译实验报告+源代码

编译实验报告+源代码

课程设计报告( 2013-- 2014年度第1学期)名称:编译技术课程设计B题目:简单编译程序的设计与实现院系:计算机系班级:XXX学号:XXX学生姓名:XXX指导教师:XXX设计周数:XXX成绩:日期:XX 年XX 月实验一.词法分析器的设计与实现一、课程设计(综合实验)的目的与要求1.1 词法分析器设计的实验目的本实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。

通过这个实验,使学生应用编译程序设计的原理和技术设计出词法分析器,了解扫描器的组成结构,不同种类单词的识别方法。

能使得学生在设计和调试编译程序的能力方面有所提高。

为将来设计、分析编译程序打下良好的基础。

1.2 词法分析器设计的实验要求设计一个扫描器,该扫描器是一个子程序,其输入是源程序字符串,每调用一次识别并输出一个单词符号。

为了避免超前搜索,提高运行效率,简化扫描器的设计,假设该程序设计语言中,基本字(也称关键词)不能做一般标识符用,如果基本字、标识符和常数之间没有确定的运算符或界符作间隔,则用空白作间隔。

单词符号及其内部表示如表1-1所示,单词符号中标识符由一个字母后跟多个字母、数字组成,常数由多个十进制数字组成。

单词符号的内部表示,即单词的输出形式为二元式:(种别编码,单词的属性值)。

表1-1 单词符号及其内部表示二、设计(实验)正文1.词法分析器流程图2.词法分析器设计程序代码// first.cpp : 定义控制台应用程序的入口点。

//#include"stdafx.h"#include<iostream>#include<string>using namespace std;int what(char a){if((int(a)>=48)&&(int(a)<=57)){return 0;//0-9数字}elseif((int(a)>=97)&&(int(a)<=122)){return 1;//a-z的字母}else{return 2;//其他的标点符号}}void scan(char a[],int &m,char zc[100][100],int &n){char zh[100];int b=0,weizhi,r=0;int zbbm;//-----------------------------检测整形常数while(a[m]==' '){cout<<"遇到空格"<<endl;m++;}if(what(a[m])==0){while(what(a[m])==0){b=b*10+int(a[m])-48;m++;}zbbm=7;cout<<"("<<zbbm<<","<<b<<")"<<endl;}else//----------------------------------检测字符型if(what(a[m])==1){if((a[m]=='b')&&(a[m+1]=='e')&&(a[m+2]=='g')&&(a[m+3]=='i')&&(a[m+4]=='n')& &(what(a[m+5])==2)){m=m+5;zbbm=1;cout<<"("<<zbbm<<",-)"<<endl;}//=====检测beginelseif((a[m]=='i')&&(a[m+1]=='f')&&(what(a[m+2])==2)){m=m+2;zbbm=2;cout<<"("<<zbbm<<",-)"<<endl;}//检测ifelseif((a[m]=='t')&&(a[m+1]=='h')&&(a[m+2]=='e')&&(a[m+3]=='n')&&(what(a[m+4])= =2)){m=m+4;zbbm=3;cout<<"("<<zbbm<<",-)"<<endl;}//检测thenelseif((a[m]=='e')&&(a[m+1]=='l')&&(a[m+2]=='s')&&(a[m+3]=='e')&&(what(a[m+4])= =2)){m=m+4;zbbm=4;cout<<"("<<zbbm<<",-)"<<endl;}//检测elseelseif((a[m]=='e')&&(a[m+1]=='n')&&(a[m+2]=='d')&&(what(a[m+3])==2)){m=m+3;zbbm=5;cout<<"("<<zbbm<<",-)"<<endl;}//检测end//----------------------------对未知字符的检测else{int j=0;while(what(a[m])!=2){zh[j]=a[m];m++;j++;}zh[j]='#';if(n==0){j=0;while(zh[j]!='#'){zc[0][j]=zh[j];j++;}zc[0][j]='#';n=1;weizhi=1;}elseif(n>0){int k=0,y=1;while((k<n)&&(y==1)){r=0;while(zc[k][r]!='#'){r++;}if(r!=j){k++;y=1;}elseif(r==j){r=0;while((int(zc[k][r])==int(zh[r]))&&(r<j)){r++;}if(r==j){weizhi=k+1;y=0;}else{k++;y=1;}}}if(y==1){j=0;while(zh[j]!='#'){zc[n][j]=zh[j];j++;}zc[n][j]='#';n=n+1;weizhi=n;}}zbbm=6;//怎么输出地址cout<<"("<<zbbm<<","<<weizhi<<")"<<endl;}}elseif(what(a[m])==2){if(a[m]=='+'){zbbm=8;m++;cout<<"("<<zbbm<<",-)"<<endl;}//检测+elseif(a[m]=='('){zbbm=11;m++;cout<<"("<<zbbm<<",-)"<<endl;}//检测(elseif(a[m]==')'){zbbm=12;m++;cout<<"("<<zbbm<<",-)"<<endl;}//检测)elseif(a[m]=='*'){if(a[m+1]=='*'){zbbm=10;m+=2;}else{zbbm=9;m++;}cout<<"("<<zbbm<<",-)"<<endl;}}}int main(){char zc[100][100];int n=0;cout<<"begin------------1"<<endl;cout<<"if ------------2"<<endl;cout<<"then ------------3"<<endl;cout<<"else ------------4"<<endl;cout<<"end ------------5"<<endl;cout<<"标志符------------6"<<endl;cout<<"整型常数------------7"<<endl;cout<<"+------------8"<<endl;cout<<"*------------9"<<endl;cout<<"**------------10"<<endl;cout<<"(------------11"<<endl;cout<<")------------12"<<endl;cout<<"========================================================="<<endl;cout<<endl;int m=0;char a[100];cout<<"请输入测试语句:";cin.getline(a,100,'\n');cout<<"输出格式为: (种别编码,单词的属性值)"<<endl;while(a[m]!='#'){scan(a,m,zc,n);}return 0;}3.词法分析器运行结果实验二. 算符优先分析的设计与实现一、课程设计(综合实验)的目的与要求2.1 算符优先分析程序设计的实验目的本实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。

编译技术课程设计报告

编译技术课程设计报告

编译技术课程设计班级软件1001学号姓名指导老师2013年 6 月目录一、目的 (2)二、任务及要求 (2)三、实验环境 (4)四、实现过程说明 (4)1.词法分析器 (4)(1)单词符号表 (4)(2)数据结构 (4)(3)函数说明 (5)(4)流程图 (5)2.语法分析器 (7)(1)分析方法说明 (7)(2)文法 (7)(3)数据结构 (9)(4)函数说明 (10)3.中间代码生成器 (10)(1)属性文法 (10)(2)数据结构 (10)(3)函数说明 (11)(4)流程图 (11)五、程序运行结果 (12)六、总结 (19)一、目的<<编译技术>>是理论与实践并重的课程,而其课程设计要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。

二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内码值如下表:对于这个小语言,有几点重要的限制:首先,所有的关键字(如if﹑while等)都是“保留字”。

所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。

例如,下面的写法是绝对禁止的: if(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。

也就是说,对于关键字不专设对应的转换图。

但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。

当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。

再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。

例如,一个条件语句应写为 if i>0 i= 1;而绝对不要写成ifi>0 i=1;因为对于后者,我们的分析器将无条件地将ifi看成一个标识符。

编译课程设计报告

编译课程设计报告

编译课程设计报告课程设计任务书学生姓名:马惠枝专业班级:计算机0902班指导教师:工作单位:计算机科学与技术学院题目: FOR循环语句的翻译程序设计(LL(1)法、输出四元式)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。

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

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

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。

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

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

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

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

课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。

时间安排:设计安排一周:周1、周2:完成系统分析及设计。

周3、周4:完成程序调试及测试。

周5:撰写课程设计报告。

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

设计报告书收取时间:设计周的次周星期一上午10点。

指导教师签名: 2010年 11月23日系主任(或责任教师)签名: 2010年 11月 23日FOR循环语句的翻译程序设计---- LL(1)法、输出四元式1.系统描述1.1程序设计要求通过设计、编制、调试一个FOR( )循环语句的词法、语法及语义分析程序,实现对于FOR( )循环语句的翻译,加深对LL(1)文法的认识,掌握这种自顶向下的文法分析方法。

首先,设计出一个关于FOR( )循环语句的文法,通过消除左递归使它符合LL(1)即递归下降法的要求;然后按照这个文法构造出文法的预测分析表、及文法橘子的分析过程,通过仔细的研究之后设计出一个集词法分析、语法分析和语义分析为一体的程序,从文法开始法号根据相应的产生式推到出相应的句子,最终输出四元式形式的中间代码。

编译实习报告

编译实习报告

编译实习报告篇一:篇一:编译原理实习报告实习报告【实习目的】1.了解编译器的工作原理2.掌握并加深本学期所学的编译原理的理论知识3.加强自己的动手能力【实习内容】1.编译并运行老师所给的编译器参考代码2.在第一步的基础上进一步改进编译器,增加输入输出功能【开发平台】window系统,free pascal编译器【实习过程】本次实习过程根据实习内容共分两大部分,第一部分,编译运行参考代码;第二部分,进一步改进编译器。

本人在上面的基础上又增加了第三部分的额外修改。

下面便总结这三部分的实习过程:一、增加读写语句前pl0编译程序由于最原始的pl0编译程序所用的pascal版本较老,有些和当前使用版本不兼容。

必须作相应修改,具体是:“object”和“procedure”为pascal的保留字,现分别改成“obj”和“proc”。

此外,原始程序中的“≠”、“≤”和“≥”,不能用ascii 码表示出来,现将其替换成“”、“=”。

作为一个编译程序,支持批量处理和永久保存是其应具备的基本功能。

为此,本程序加入了文件读写功能,即从文件读入pl0源程序,在将中间代码和运行结果写入文件。

由于源程序和原始差别很小,为节省篇幅,不将其打印出来。

二、增加读写语句前pl0调试程序下面是增加读写语句前的pl0程序,包含了乘、除法和寻找两个自然数的最大公因数的过程和主过程,很好的说明了增加读写语句前的pl0语言的使用方法。

constvarx,y,z,q,r; procedure multiply; var a,b; a:=x; begin m=7,n=85;procedure divide; var end; b:=y; z:=0; while b>0 do begin end if odd b then z:=z+a; a:=2*a; b:=b/2;w;beginr:=x;q:=0;w:=y;while wy dobegin q:=2*q; w:=w/2;if wg dobeginif f0 do 13begin13 if odd b then z:=z+a; 20 a:=2*a;24 b:=b/2; 28end28 end;2 int 0 53 lod 1 34 sto 0 35 lod 1 46 sto 0 47 lit 0 08 sto 1 59 lod 0 410 lit 0 011 opr 01212 jpc 02913 lod 0 414 opr 0 615 jpc 02016 lod 1 517 lod 0 318 opr 0 219 sto 1 520 lit 0 221 lod 0 322 opr 0 423 sto 0 324 lod 0 425 lit 0 226 opr 0 527 sto 0 428 jmp 0 929 opr 0 03030 procedure divide;30 var31w;31 begin32r:=x;34q:=0;36w:=y;38while wy do51begin q:=2*q; w:=w/2;59 if w篇二:编译原理实习报告实习报告【实习目的】1.了解编译器的工作原理2.掌握并加深本学期所学的编译原理的理论知识3.加强自己的动手能力【实习内容】1.编译并运行老师所给的编译器参考代码2.在第一步的基础上进一步改进编译器,增加输入输出功能【开发平台】Window系统,Free Pascal编译器【实习过程】本次实习过程根据实习内容共分两大部分,第一部分,编译运行参考代码;第二部分。

编译实习报告

编译实习报告

编译实习报告一、实习背景随着计算机技术的不断发展,编译技术在软件开发和计算机科学领域中起着至关重要的作用。

为了更好地了解编译原理在实际应用中的具体实现,提高自己的实际动手能力,我参加了为期三个月的编译实习项目。

在实习期间,我深入学习了编译原理的基本知识,并参与了编译器的开发与优化过程。

二、实习内容1. 编译原理学习在实习的第一阶段,我系统地学习了编译原理的基本知识,包括文法、语法分析、中间代码生成、代码优化和目标代码生成等。

通过学习,我掌握了编译器的基本组成部分及其工作原理,为后续的实践操作打下了坚实的基础。

2. 编译器开发在实习的第二阶段,我参与了编译器的开发过程。

首先,我使用C语言编写了一个简单的编译器前端,实现了源代码的词法分析和语法分析。

在此基础上,我进一步实现了中间代码的生成和代码优化模块。

最后,我完成了目标代码的生成和运行。

整个过程中,我深刻体会到了编译原理在实际应用中的重要性。

3. 编译器优化在实习的第三阶段,我主要负责编译器的优化工作。

通过对中间代码的分析和调整,我实现了常数折叠、死代码消除和循环优化等优化策略。

经过优化,编译器生成的目标代码在运行效率和内存占用方面都有了显著的提升。

三、实习收获1. 知识运用通过实习,我将所学的编译原理知识运用到了实际项目中,提高了自己的实际动手能力。

同时,实习过程中遇到的问题也促使我不断深入学习相关知识,提高了自己的理论水平。

2. 团队协作在实习过程中,我与团队成员密切配合,共同解决问题。

这使我更加明白了团队协作的重要性,也锻炼了我的沟通与协作能力。

3. 工程实践实习过程中,我独立完成了编译器的开发与优化任务,掌握了工程实践的基本方法。

这对我今后从事软件开发工作具有很大的帮助。

四、实习总结通过这次编译实习,我对编译原理有了更深入的了解,并在实际项目中积累了宝贵的经验。

同时,实习过程中的挑战和困难也让我明白了自身存在的不足,为我今后的学习和工作指明了方向。

实验报告编译实验

实验报告编译实验

一、实验目的1. 理解编译原理的基本概念和过程。

2. 掌握编译器的基本组成和编译流程。

3. 学会使用编译器对源代码进行编译,并分析编译结果。

二、实验环境1. 操作系统:Windows 102. 编译器:GCC (GNU Compiler Collection)3. 开发工具:Visual Studio Code三、实验内容1. 编译器的基本组成和编译流程2. 编译器的使用3. 编译结果分析四、实验步骤1. 编译器的基本组成和编译流程(1)词法分析:将源代码分解成一个个的单词,如标识符、关键字、运算符等。

(2)语法分析:将单词序列转换成语法树,验证源代码是否符合语法规则。

(3)语义分析:检查语法树,确保源代码在语义上是正确的。

(4)中间代码生成:将语法树转换成中间代码,如三地址代码。

(5)代码优化:对中间代码进行优化,提高程序运行效率。

(6)目标代码生成:将优化后的中间代码转换成目标代码,如汇编代码。

(7)代码生成:将目标代码转换成可执行文件。

2. 编译器的使用(1)编写源代码:使用Visual Studio Code编写C语言源代码。

(2)编译源代码:在命令行中输入gcc -o 程序名源文件名.c,编译源代码。

(3)运行程序:在命令行中输入程序名,运行编译后的程序。

3. 编译结果分析(1)词法分析:编译器将源代码中的单词进行分解,如以下代码:```cint main() {int a = 1;return a;}```编译器将分解为以下单词:- int- main- (- )- {- int- a- =- 1- ;- return- a- ;- }- }(2)语法分析:编译器将单词序列转换成语法树,验证源代码是否符合语法规则。

(3)语义分析:编译器检查语法树,确保源代码在语义上是正确的。

(4)中间代码生成:编译器将语法树转换成中间代码,如以下三地址代码:```t1 = 1a = t1t2 = areturn t2```(5)代码优化:编译器对中间代码进行优化,如以下优化后的三地址代码:```a = 1return a```(6)目标代码生成:编译器将优化后的中间代码转换成汇编代码。

编译课程设计报告

编译课程设计报告

编译课程设计报告一、教学目标本课程的教学目标是使学生掌握编译原理的基本概念、方法和算法,培养学生运用编译原理解决实际问题的能力。

具体目标如下:1.知识目标:(1)了解编译原理的基本概念,如编译器、源语言、目标语言等。

(2)掌握编译过程中的各个阶段,如词法分析、语法分析、语义分析、中间代码生成、目标代码生成等。

(3)熟悉常见编译优化技术,如代码简化、死代码消除、循环优化等。

(4)了解编译器实现的基本方法,如递归下降分析、LL分析、LR分析等。

2.技能目标:(1)能够使用编译原理相关工具,如lex、yacc等。

(2)具备简单的编译器设计与实现能力。

(3)能够分析程序的性能,并应用编译优化技术进行优化。

3.情感态度价值观目标:(1)培养学生对编译原理的兴趣,提高学生自主学习的积极性。

(2)培养学生团队合作精神,提高学生解决实际问题的能力。

二、教学内容本课程的教学内容主要包括以下几个部分:1.编译原理基本概念:介绍编译器、源语言、目标语言等基本概念。

2.编译过程及其各个阶段:讲解词法分析、语法分析、语义分析、中间代码生成、目标代码生成等阶段。

3.编译优化技术:介绍代码简化、死代码消除、循环优化等优化技术。

4.编译器实现方法:讲解递归下降分析、LL分析、LR分析等实现方法。

5.编译器工具使用:介绍lex、yacc等工具的使用方法。

6.编译器设计与实现:讲解编译器的设计与实现过程。

三、教学方法本课程采用讲授法、讨论法、案例分析法和实验法等多种教学方法,以激发学生的学习兴趣和主动性。

1.讲授法:用于讲解编译原理的基本概念、方法和算法。

2.讨论法:学生针对编译原理中的重点、难点问题进行讨论,提高学生的理解能力。

3.案例分析法:通过分析实际案例,使学生更好地掌握编译原理的应用。

4.实验法:让学生亲自动手实现简单的编译器,提高学生的实践能力。

四、教学资源本课程的教学资源包括教材、参考书、多媒体资料和实验设备等。

1.教材:选用《编译原理》等权威教材,为学生提供系统、科学的学习资料。

编译原理实验报告

编译原理实验报告

编译原理实验报告一、实验目的编译原理是计算机科学中的重要课程,旨在让学生了解编译器的基本工作原理以及相关技术。

本次实验旨在通过设计和实现一个简单的编译器,来进一步加深对编译原理的理解,并掌握实际应用的能力。

二、实验环境本次实验使用了Java编程语言及相关工具。

在开始实验前,我们需要安装Java JDK并配置好运行环境。

三、实验内容及步骤1. 词法分析词法分析是编译器的第一步,它将源代码分割成一系列词法单元。

我们首先实现一个词法分析器,它能够将输入的源代码按照语法规则进行切割,并识别出关键字、标识符、数字、运算符等。

2. 语法分析语法分析是编译器的第二步,它将词法分析得到的词法单元序列转化为语法树。

我们使用自顶向下的LL(1)语法分析算法,根据文法规则递归地构建语法树。

3. 语义分析语义分析是编译器的第三步,它对语法树进行检查和转换。

我们主要进行类型检查、语法错误检查等。

如果源代码存在语义错误,编译器应该能够提供相应的错误提示。

4. 代码生成代码生成是编译器的最后一步,它将经过词法分析、语法分析和语义分析的源代码翻译为目标代码。

在本次实验中,我们将目标代码生成为Java字节码。

5. 测试与优化完成以上步骤后,我们需要对编译器进行测试,并进行优化。

通过多个测试用例的执行,我们可以验证编译器的正确性和性能。

四、实验心得通过完成这个编译器的实验,我收获了很多。

首先,我对编译原理的知识有了更深入的理解。

在实验过程中,我深入学习了词法分析、语法分析、语义分析和代码生成等关键技术,对编译器的工作原理有了更系统的了解。

其次,我提高了编程能力。

实现一个完整的编译器需要处理复杂的数据结构和算法,这对我的编程能力是一个很好的挑战。

通过实验,我学会了合理地组织代码,优化算法,并注意到细节对程序性能的影响。

最后,我锻炼了解决问题的能力。

在实验过程中,我遇到了很多困难和挑战,但我不断地调试和改进代码,最终成功地实现了编译器。

编译原理实验报告小结

编译原理实验报告小结

一、实验背景编译原理是计算机科学的一个重要分支,主要研究如何将高级语言源代码转换为计算机可以执行的机器代码。

本实验旨在通过实践操作,加深对编译原理基本概念和算法的理解,提高编程能力和解决问题的能力。

二、实验目的1. 理解编译原理的基本概念和流程;2. 掌握词法分析和语法分析的基本方法;3. 熟悉编译过程中的中间代码生成和代码优化;4. 培养编程能力和团队协作精神。

三、实验内容1. 词法分析词法分析是编译过程的第一步,其主要任务是将源代码中的字符序列转换成一个个有意义的符号(单词)。

本实验中,我们实现了词法分析器,能够识别出标识符、关键字、运算符、常量等单词。

2. 语法分析语法分析是编译过程的核心,其主要任务是将词法分析器生成的单词序列按照一定的语法规则进行组织,形成语法树。

本实验中,我们实现了递归下降解析法,对表达式、赋值语句、函数定义等语法结构进行了分析。

3. 中间代码生成中间代码生成是编译过程中的一个重要环节,其主要任务是将语法树转换为一种抽象的、与具体机器无关的中间代码。

本实验中,我们实现了三地址代码生成,将语法树转换为三地址代码。

4. 代码优化代码优化是编译过程中的一个关键步骤,其主要任务是在保证程序正确性的前提下,提高程序的性能。

本实验中,我们实现了简单的代码优化,如常数传播、变量替换等。

四、实验结果与分析1. 实验结果通过实验,我们成功实现了词法分析、语法分析、中间代码生成和代码优化等功能。

以一个简单的C语言程序为例,我们能够将其转换为三地址代码,并进行简单的优化。

2. 实验分析(1)词法分析:本实验中,我们通过定义状态转换表和动作表,实现了对C语言源代码的词法分析。

实验结果表明,词法分析器能够准确地识别出标识符、关键字、运算符、常量等单词。

(2)语法分析:递归下降解析法是一种较为直观的语法分析方法。

本实验中,我们实现了递归下降解析法,对表达式、赋值语句、函数定义等语法结构进行了分析。

编译技术实验报告

编译技术实验报告

编译技术实验报告
编译技术实验报告是每个程序员与编程相关的任务中都非常重要的一部分,它能让他们更好的深入理解为什么程序能在机器上运行,以及它在什么情况下会失去有效性。

编译技术实验报告是一个程序的思考、测试和分析的下一步,以确保程序的性能得到可靠的运行和改进。

首先,程序员在编辑器中使用语言来构建程序。

然后,使用编译器将源代码生成可执行文件,将源代码翻译成机器可以理解的语言,使其在机器上可以运行代码。

在它完成后,程序员就可以通过编译技术实验报告,测试程序是否正确、优化其性能、增强其可用性、甚至查找隐藏的错误等。

特别是在编写嵌入式程序时,编译技术实验报告尤为重要,因为它可以在发布时发现隐藏的Bug,而没有这一步就无法确保程序的完美运行。

此外,编译技术实验报告还可以帮助程序员发现程序的内在缺陷,例如发现变量的重复初始化、变量的名称未定义或程序函数将活动超出其规格等。

这样可以保证程序在发布时无bug可言,从而提高程序的可用性。

总之,编译技术实验报告是一种在程序发布之前及时发现并修复Bug的重要手段。

它可以提高程序的性能、便捷性和有效性,使其达到最佳的运行状态。

无论程序员采用何种程序设计语言,在发布前都一定要注意进行实验报告,严格检查程序中可能存在的bug。

这样可以确保程序能够顺利发布,且不会因Bug引起用户不满。

编译系统设计实验报告

编译系统设计实验报告

实验名称:编译系统设计实验时间:2023年X月X日实验地点:XX大学计算机学院实验室实验人数:XX人实验指导老师:XX教授一、实验目的1. 理解编译系统的基本概念和原理。

2. 掌握编译器各个阶段的设计和实现方法。

3. 提高编程能力和系统设计能力。

二、实验内容本次实验主要分为以下几个阶段:1. 词法分析阶段:将源代码中的字符序列转换为一个个词法符号。

2. 语法分析阶段:根据词法符号生成抽象语法树(AST)。

3. 语义分析阶段:对AST进行语义检查,确保程序的语义正确性。

4. 中间代码生成阶段:将AST转换为中间代码。

5. 代码优化阶段:对中间代码进行优化,提高程序运行效率。

6. 目标代码生成阶段:将优化后的中间代码转换为特定机器语言的目标代码。

7. 符号表管理阶段:在整个编译过程中,对符号进行管理。

三、实验步骤1. 设计词法分析器(1)定义词法符号集合:根据源代码的特点,定义词法符号集合,如标识符、关键字、运算符等。

(2)编写词法分析器代码:使用正则表达式或有限状态自动机实现词法分析器。

2. 设计语法分析器(1)定义语法规则:根据源代码的语法规则,定义语法规则。

(2)编写语法分析器代码:使用递归下降分析法或LL(1)分析算法实现语法分析器。

3. 设计语义分析器(1)定义语义规则:根据源代码的语义要求,定义语义规则。

(2)编写语义分析器代码:对AST进行遍历,检查语义正确性。

4. 设计中间代码生成器(1)定义中间代码格式:根据源代码的特点,定义中间代码格式。

(2)编写中间代码生成器代码:将AST转换为中间代码。

5. 设计代码优化器(1)选择优化策略:根据中间代码的特点,选择合适的优化策略。

(2)编写代码优化器代码:对中间代码进行优化。

6. 设计目标代码生成器(1)定义目标代码格式:根据目标机器的特点,定义目标代码格式。

(2)编写目标代码生成器代码:将优化后的中间代码转换为目标代码。

7. 设计符号表管理器(1)定义符号表结构:根据源代码的特点,定义符号表结构。

编译实习报告

编译实习报告

篇一:编译原理实习报告实习报告【实习目的】1.了解编译器的工作原理2.掌握并加深本学期所学的编译原理的理论知识3.加强自己的动手能力【实习内容】1.编译并运行老师所给的编译器参考代码2.在第一步的基础上进一步改进编译器,增加输入输出功能【开发平台】window系统,free pascal编译器【实习过程】本次实习过程根据实习内容共分两大部分,第一部分,编译运行参考代码;第二部分,进一步改进编译器。

本人在上面的基础上又增加了第三部分的额外修改。

下面便总结这三部分的实习过程:一、增加读写语句前pl0编译程序由于最原始的pl0编译程序所用的pascal版本较老,有些和当前使用版本不兼容,必须作相应修改,具体是:“object”和“procedure”为pascal的保留字,现分别改成“obj”和“proc”。

此外,原始程序中的“≠”、“≤”和“≥”,不能用ascii码表示出来,现将其替换成“&lt;&gt;”、“&lt;=”和“&gt;=”。

作为一个编译程序,支持批量处理和永久保存是其应具备的基本功能。

为此,本程序加入了文件读写功能,即从文件读入pl0源程序,在将中间代码和运行结果写入文件。

由于源程序和原始差别很小,为节省篇幅,不将其打印出来。

二、增加读写语句前pl0调试程序下面是增加读写语句前的pl0程序,包含了乘、除法和寻找两个自然数的最大公因数的过程和主过程,很好的说明了增加读写语句前的pl0语言的使用方法。

constvarx,y,z,q,r; procedure multiply; var a,b; a:=x; begin m=7,n=85;procedure divide; var end; b:=y; z:=0; while b&gt;0 do begin end if odd b then z:=z+a; a:=2*a; b:=b/2;w;beginr:=x;q:=0;w:=y;while w&lt;=r do w:=2*w;while w&gt;y dobegin q:=2*q; w:=w/2;if w&lt;=r thenbeginr:=r-w;q:=q+1endendend;procedure gcd;varf,g;beginf:=x;g:=y;while f&lt;&gt;g dobeginif f&lt;g then g:=g-f;if g&lt;f then f:=f-g;end;z:=fend;beginx:=m;y:=n;call multiply;y:=3;call divide;x:=84;y:=36;call gcd;end.三、增加读写语句前pl0编译程序生成的中间代码下面所给清单是用(一)中增加读写语句前pl0编译程序对(二)中的pl0程序编译生成的中间代码。

编译原理教程实验报告

编译原理教程实验报告

一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。

二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。

2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。

3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。

4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。

5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。

6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。

四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。

2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。

3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。

4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。

5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。

6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。

五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。

编译课程设计报告书

编译课程设计报告书

编译课程设计报告书课程设计报告( 2011 -- 2012年度第 1 学期)名称:编译技术课程设计B题目:词法分析器设计算符优先分析程序设计基于算符优先分析方法的语法制导翻译程序设计院系:计算机系班级:网络学号:学生姓名:指导教师:岳燕黄建才设计周数:1周成绩:日期:2012年1月6日一、课程设计的目的与要求1.词法分析器设计的目的与要求1.1 词法分析器设计的目的实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。

通过这个实验,使学生应用编译程序设计的原理和技术设计出词法分析器,了解扫描器的组成结构,不同种类单词的识别方法。

能使得学生在设计和调试编译程序的能力方面有所提高。

为将来设计、分析编译程序打下良好的基础。

1.2 词法分析器设计的要求设计一个扫描器,该扫描器是一个子程序,其输入是源程序字符串,每调用一次识别并输出一个单词符号。

为了避免超前搜索,提高运行效率,简化扫描器的设计,假设该程序设计语言中,基本字(也称关键词)不能做一般标识符用,如果基本字、标识符和常数之间没有确定的运算符或界符作间隔,则用空白作间隔。

单词符号及其内部表示如表1-1所示,单词符号中标识符由一个字母后跟多个字母、数字组成,常数由多个十进制数字组成。

单词符号的内部表示,即单词的输出形式为二元式:(种别编码,单词的属性值)。

表1-1 单词符号及其内部表示单词符号种别编码单词的属性值BEGIN IF 12——THEN ELSE END标识符整型常数+***()3456789101112———在名字表中的地址十进制整数—————2.算符优先分析程序设计的目的与要求2.1 算符优先分析程序设计的目的本实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。

通过这个实验,使学生应用编译程序设计的原理和技术, 设计、编写和调试算符优先分析程序,了解算符优先分析程序的组成结构,掌握实现通用算符优先分析算法的方法。

编译软件实验报告

编译软件实验报告

一、实验目的本次实验旨在通过编译软件的学习和实践,使学生掌握编译软件的基本原理和实现方法,提高学生编程能力和软件设计能力。

通过本次实验,学生应能够:1. 理解编译软件的基本概念和作用;2. 掌握编译软件的基本结构和工作流程;3. 学会使用编译软件进行程序编译;4. 了解编译软件的优化方法和性能评估;5. 培养团队合作精神和实践创新能力。

二、实验环境1. 操作系统:Windows 102. 编译软件:GCC(GNU Compiler Collection)3. 编程语言:C/C++4. 开发工具:Visual Studio Code三、实验内容1. 编译软件的基本概念和作用编译软件是将高级语言程序转换为机器语言程序的软件。

它主要包括词法分析、语法分析、语义分析、代码生成和优化等阶段。

编译软件的作用是将程序员编写的高级语言程序转换为计算机能够理解和执行的机器语言程序,从而实现程序的执行。

2. 编译软件的基本结构和工作流程编译软件的基本结构包括词法分析器、语法分析器、语义分析器、中间代码生成器、代码优化器和目标代码生成器等模块。

工作流程如下:(1)词法分析:将源代码中的字符序列转换为单词序列;(2)语法分析:根据语法规则对单词序列进行语法分析,生成抽象语法树(AST);(3)语义分析:对AST进行语义检查,确定变量的作用域、类型等;(4)中间代码生成:将AST转换为中间代码;(5)代码优化:对中间代码进行优化,提高程序执行效率;(6)目标代码生成:将优化后的中间代码转换为机器语言程序。

3. 编译软件的使用(1)编写C/C++程序:使用Visual Studio Code编写C/C++程序,保存为`.c`或`.cpp`文件。

(2)编译程序:在命令行中使用GCC编译器编译程序。

例如,编译名为`main.c`的程序,可以使用以下命令:```gcc -o main main.c```编译成功后,会在当前目录下生成名为`main`的可执行文件。

编译实验报告

编译实验报告
cbuffer=digitprocess(cbuffer);
else cbuffer=otherprocess(cbuffer);
}
printf("Anysis End\n");
getchar();
}
}
7、测试及结果
11.txt内容:main{int a,b;a = 10;b = a + 20;}
8、心得
return(0);
case 3:
for (i=0;i<=4;i++)
if (strcmp(arithmetic[i],searchchar)==0) return(i+1);
return(0);
case 4:
for (i=0;i<=5;i++)
if (strcmp(relation[i],searchchar)==0) return(i+1);
#include <stack>
using namespace std;
char Vn[]={'E','e','T','t','F'}; //定义文法的非终结符,小写字母e表示E’
char Vt[]={'i','+','*','(',')','#'}; //定义文法的终结符
int LENVt=sizeof(Vt);
{
int i=0;
switch (wordtype)
{
case 1:
for (i=0;i<=7;i++)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计报告( 2010 -- 2011年度第 1 学期)名称:编译技术课程设计B题目:词法分析器设计算符优先分析程序设计基于算符优先分析方法的语法制导翻译程序设计院系:计算机系班级:网络0802学号:学生姓名:指导教师:黄志强阎蕾岳燕设计周数:1周成绩:日期:2010年12月31一、课程设计的目的与要求1.词法分析器设计的目的与要求1.1 词法分析器设计的实验目的本实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。

通过这个实验,使学生应用编译程序设计的原理和技术设计出词法分析器,了解扫描器的组成结构,不同种类单词的识别方法。

能使得学生在设计和调试编译程序的能力方面有所提高。

为将来设计、分析编译程序打下良好的基础。

1.2 词法分析器设计的实验要求设计一个扫描器,该扫描器是一个子程序,其输入是源程序字符串,每调用一次识别并输出一个单词符号。

为了避免超前搜索,提高运行效率,简化扫描器的设计,假设该程序设计语言中,基本字(也称关键词)不能做一般标识符用,如果基本字、标识符和常数之间没有确定的运算符或界符作间隔,则用空白作间隔。

单词符号及其内部表示如表1-1所示,单词符号中标识符由一个字母后跟多个字母、数字组成,常数由多个十进制数字组成。

单词符号的内部表示,即单词的输出形式为二元式:(种别编码,单词的属性值)。

表1-1 单词符号及其内部表示2.算符优先分析程序设计的目的和要求2.1 算符优先分析程序设计的实验目的本实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。

通过这个实验,使学生应用编译程序设计的原理和技术, 设计、编写和调试算符优先分析程序,了解算符优先分析程序的组成结构,掌握实现通用算符优先分析算法的方法。

能使得学生在设计和调试编译程序的能力方面有所提高。

为将来设计、分析编译程序打下良好的基础。

2.2 算符优先分析程序设计的实验要求算符优先分析属于自下而上的分析方法,该语法分析程序的输入是终结符号串(即单词符号串,以一个“#”结尾),如果输入串是句子则输出“YES”,否则输出“NO”和错误信息。

算符优先分析过程与非终结符号无关,当由文法产生了优先关系之后文法也就失去了作用,本题目给出文法的目的是为了便于对语法分析结果进行验证。

(1)文法设算符优先文法G为:+→E|ETT*T|→FFT↑→F|PPF→(iP|)E说明:i为整型常数或者为标识符表示整型变量;使用中↑用**表示。

(2)优先关系表设优先关系表如表1-2所示。

表1-2 优先关系表3.基于算符优先分析方法的语法制导翻译程序设计的目的和要求3.1基于算符优先分析方法的语法制导翻译程序设计的实验目的本实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。

通过这个实验,使学生应用编译程序设计的原理和技术, 通过设计、编写和调试语法制导翻译程序,掌握从一种语句的语法和语义出发,构造相应的语义子程序,实现基于算符优先分析方法的语法制导翻译的方法。

能使得学生在设计和调试编译程序的能力方面有所提高。

为将来设计、分析编译程序打下良好的基础。

3.2 基于算符优先分析方法的语法制导翻译程序设计的实验要求算符优先分析方法是通过反复把输入符号移进分析栈,使用优先关系表在分析栈顶寻找最左素短语,将其归约为一个非终结符号而实现的。

这个分析过程与非终结符号无关,当由文法产生了优先关系之后文法也就失去了作用(所以本题目无需给出文法)。

基于算符优先分析方法的语法制导翻译是在算符优先语法分析的基础上进行翻译工作(即语义分析),每当将一个最左素短语归约为一个非终结符号时,就调用对应产生式的语义子程序,去完成相应的语义翻译工作,这步归约使用的产生式对非终结符号不加区分(即将所有的非终结符号用一个通用的非终结符号表示)。

语法制导翻译程序的输入是终结符号串(即单词符号串,以一个“#”结尾),如果输入符号串是句子,则按照其语义进行翻译,输出等价的四元式序列(作为练习应显示输出)。

二、课程设计正文1.词法分析器设计1.1 以文件流的方式对词法进行输入句子。

1.2 标识符和常数的属性值(1)标识符和常数的属性值为该单词在名次表或常数表中登机项的相对地址;(2)当识别出一个标识符或常数时,要查名字表或常数表,若表中有其登记项,则把得到的登记项地址作为其属性值;(3)若表中没有其登记项,则建立一个新登记项,该登记项地址作为其属性值,此处的地址为在表中的下标。

1.3 主要数据结构(1)属性类Dog,内含某一单词的显示字符串和类别,类别包括关键字、标识符、常数;(2)输入缓冲区Buffer[100],类型为字符型;(3)关键字表Letter[],类型为Dog;(4)标识符表Varible[],类型为Dog,存储在句子中出现过的标识符;(5)常数表Constant[],类型为Dog,存储在句子中出现过的常数;(6)设置全局变量b,v,c,l记录输入缓冲区、标识符表、常数表、关键字表的当前最后一个指针。

1.4 词法错误处理:出错则显示错误所在字符位置。

2.算符优先分析程序设计2.1 以文件流的方式对词法进行输入句子。

2.2 主要数据结构(1)优先关系表XX[],全局变量,事先设定;(2)分析栈类Stack,内含数组array[]存储终结符号、“#”、非终结符N,和数组array[]的长度size;(3)数组str[],用于存放输入字符串。

2.3 算法主要使用两个while嵌套循环,外层为当前字符a不为#则继续,内层循环当前字符a与其后一个终结符的相对优先关系为大于时,则进行规约,否则执行移入操作;2.4 当分析栈中进入‘#’,且分析栈中只剩三个字符时,表示分析成功,否则失败。

2.5 出错则显示错误所在字符位置。

3.基于算符优先分析方法的语法制导翻译程序的设计3.1 该实验算法是在第二个实验的基础上,将规约后产生的N变为临时变量Ei或中间变量Ti,当产生中间变量的四元式时,则输出该四元式。

3.2 为实现算法,这里用到词法分析的思想,将输入字符串先通过词法分析,转化为各单词的属性值或地址值。

此做法便于实现数组的输出和查看。

三、课程设计总结或结论1.词法分析器设计在做这个实验以前一直认为编译的词法分析器是计算机内部某个硬件部分。

由于该门课程结课较早,有些内容需要重新翻书查找。

通过这次实验,我对之前学过的内容有了更深的理解,了解了扫描器的组成结构、不同种类单词的识别方法,掌握了由单词的语法规则触发、画出识别单词的状态转换图、然后再用程序实现的扫描器设计方法。

2.算符优先分析程序设计该程序的主要难点在于何时规约和何地规约,以及规约前后对几个指针位置的处理。

通过本次实验一定程度上提高了软件开发能力,对编译原理这一门课程也有了比较深刻的了解,掌握了算符优先分析方法。

最后,由于所学知识不够全面,实验在很多方面还有待完善,在以后的学习过程中,会掌握更多知识,力求做到更好。

3.基于算符优先分析方法的语法制导翻译程序的设计关于语法制导的内容之前未在课堂上有学过,首先锻炼了我的自学能力,通过学习和实践掌握了从一种语句的语法和语义出发,构造相应的语义子程序,实现语法制导翻译的方法。

这个实验有着第二个实验的基础,保持算符优先分析的整体思想,在此基础上利用词法分析器的思想设计了一段模数转换程序,将字符串转换为数字形式。

通过自己思考摸索,不断调试,最终使程序得以正常运行。

四、参考文献[1] 陈火旺,刘春林. 程序设计语言编译原理. 北京:国防工业出版社,第三版. 2008,9[2] 宋雨,程晓荣,黄志强. 计算机综合实践指导. 北京:清华大学出版社,第一版.2004,2附录(设计流程图、程序、运行结果等)(一)流程图1.词法分析器设计2.算符优先分析程序设计3.基于算符优先分析方法的语法制导翻译程序的设计(二)程序代码1.词法分析器设计#include<iostream>#include<stdlib.h>#include <ctype.h>#include<string.h>using namespace std;char strToken[20];//存当前构成字符串class Dog{char info[20];int race;public:Dog(char cc[20],int rr)//构造函数{strcpy(info,cc);race=rr;}int comp(char ss[20])//比较strToken是否为此类别,否返回0{if(strcmp(info,ss)==0)return race;return 0;}};char Buffer[100];//输入缓冲区int b;//Buffer指针char ch;//当前读进字符Dog* Varible[20];//符号表Dog* Constant[20];//常数表Dog* Letter[20];//已有单词表int v,c,l;//对应尾指针的后一个int a[2];void init0(){b=0;v=0;c=0;l=0;Letter[l++]=new Dog("BEGIN",1);Letter[l++]=new Dog("IF",2);Letter[l++]=new Dog("THEN",3);Letter[l++]=new Dog("ELSE",4);Letter[l++]=new Dog("END",5);}void init(){ch=' ';a[0]=-1;a[1]=-1;strcpy(strToken,"");}void GetChar()//取当前字符{ch=Buffer[b];b++;}void GetBC()//取字符直到不为空格{while(ch==' ')GetChar();}bool IsLetter()//判断是否为字母{if(ch>='A'&&ch<='Z')return 1;else if(ch>='a'&&ch<='z')return 1;return 0;}bool IsDigit()//判断是否为数字{if(ch>='0'&&ch<='9')return 1;return 0;}void Concat()//把字符连接到当前短语后边{strcat(strToken,&ch);}void Retract()//回退一个字符{ch=' ';b--;}int Reserve()/*整型函数过程,对strToken则可回送0值中的字符串查找保留字表,若它是一个保留字则返回它的编码;否则返回非保留字信息,譬如若0不是保留字的编码*/{int i,x;for(i=0;i<l;i++){x=Letter[i]->comp(strToken);if(x>0)return x;}return 0;}int InsertId()//整型函数过程,将strToken中的标识符插入符号表,返回符号表指针{Varible[v]=new Dog(strToken,v+1);v++;int i=v;return i;}int InsertConst()//整型函数过程,将strToken中的常数插入常数表,返回常数表指针{Constant[c]=new Dog(strToken,c+1);c++;return c;}void ProError(){cout<<endl<<"第"<<b<<"个字符\""<<Buffer[b-1]<<"\"出错"<<endl; // cout<<"errorerror!"<<endl;}void f()//词法分析器{int code, value;init();// int a[2];//作为return(种别,属性)GetChar(); GetBC();if(IsLetter()){while (IsLetter()||IsDigit()){Concat(); GetChar();}Retract();code=Reserve();if (code==0){value=InsertId();a[0]=6;//该单词为标识符a[1]=value;return;//return a;}else{a[0]=code;//该单词为保留字a[1]=-1;return;//return a;}}else if (IsDigit()){while(IsDigit()){Concat();GetChar();}Retract();value=InsertConst();a[0]=7;//该单词为常数a[1]=value;return;//return a;}else if (ch=='='){a[0]=8;a[1]=-1;return;//return a;}else if (ch=='+'){a[0]=9;a[1]=-1;return;//return a;}else if (ch=='*'){GetChar();if (ch=='*'){a[0]=11;a[1]=-1;return;//return a;}Retract();a[0]=10;a[1]=-1;return;//return a;}else if (ch==','){a[0]=12;a[1]=-1;return;//return a;}else if (ch=='('){a[0]=13;a[1]=-1;return;//return a;}else if (ch==')'){a[0]=14;a[1]=-1;return;//return a;}else ProError(); /*错误处理*/a[0]=-1;a[1]=-1;return;//return a;}void disp(){char x;// if(a[0]==-1)// ProError();if(a[1]==-1){x='-';cout<<"("<<a[0]<<","<<x<<")";}elsecout<<"("<<a[0]<<","<<a[1]<<")"; }void main(){init0();// strcpy(Buffer,"BEGIN IF ELSE abcde 1234");////////////////////////////////////////////////////////////////////char in[100]; //用于接收输入文件名// char str[100];//存句子FILE *fin; //用于指向输入文件的指针cout<<"请输入所需文件名(xxx.txt):";cin>>in;while((fin=fopen(in,"r"))==NULL) //判断输入文件名是否正确{cout<<endl<<"打开词法分析输入文件出错!"<<endl;cout<<"请重新输入:";strcpy(in,"");cin>>in;}int m=0;//记录str句子串的长度char ch1='a';while (ch1!='#')//从文件中读入一串字符{ch1=getc(fin);Buffer[m++]=ch1;}// cin>>Buffer;int lllong=m-1;// cout<<lllong<<endl;while(b<lllong){init();f();disp();}cout<<endl;// return;}2.算符优先分析程序设计#include<string.h>#include<stdlib.h>#include <ctype.h>#include<iostream>using namespace std;const int maxsize=100; //为数组str[]、in[]分配的最大存储空间const int length=100;//为数组array[]分配的最大存储空间char XX[8][8]={' ','+','*','!','i','(',')','#','+','>','<','<','<','<','>','>','*','>','>','<','<','<','>','>','!','>','>','<','<','<','>','>','i','>','>','>',' ',' ','>','>','(','<','<','<','<','<','=',' ',')','>','>','>',' ',' ','>','>','#','<','<','<','<','<',' ','='};class Stack{private:int size;//size为当前数组array[]的大小char array[length];//用于存储读入的字符public:Stack(){size=0;//数组array[]的初始长度为0 }void push(char ch){if(size<length)//如果数组未满,则压入{array[size]=ch;size++;}else//若数组已满,则给出出错信息cout<<"overflow!"<<endl;}int pop(char ch[],int len)//弹出字符准备规约{if(size-len>=0){for(int i=0;i<len;i++)ch[i]=array[size-len+i];size-=len;return len;}else{cout<<"参数错误!"<<endl;return 0;}}char judge(int pos)//判断大小是否合法{if(pos>=0&&pos<size)return array[pos];return '\0';}void disp_all()//输出当前数组中的字符{for(int i=0;i<size;i++){if(judge(i)=='!')cout<<"**";elsecout<<judge(i);}if(size>7)cout<<'\t'<<'\t';elsecout<<'\t'<<'\t'<<'\t';}int getsize()//返回当前数组大小{return size;}};char guiyue(char ch[])//规约为'N'{return 'N';}int isnumch(char ch)//判断ch是不是数字或小写字母{return (ch>='0'&&ch<='9'||ch>='a'&&ch<='z');}int getrank(char ch1,char ch2)//根据算符优先分析矩阵设置读入优先次序{ //0表示等于,1表示大于,-1表示小于,2表示没有优先关系int i,j;if(isnumch(ch1))ch1='i';if(isnumch(ch2))ch2='i';switch(ch1){case '+':i=1;break;case '*':i=2;break;case '!':i=3;break;case 'i':i=4;break;case '(':i=5;break;case ')':i=6;break;case '#':i=7;break;}switch(ch2){case '+':j=1;break;case '*':j=2;break;case '!':j=3;break;case 'i':j=4;break;case '(':j=5;break;case ')':j=6;break;case '#':j=7;break;}if(XX[i][j]=='>')return 1;else if(XX[i][j]=='<')return -1;else if(XX[i][j]=='=')return 0;elsereturn 2;}int isvt(char ch)//区别参加规约的资格{if(ch>='a'&&ch<='z')return 1;if(ch>='0'&&ch<='9')return 1;for(int i=0;i<8;i++){if(ch==XX[0][i])return 1;}return 0;}/****************主函数**************/void main(){cout<<"====================该文法的算符优先矩阵如下==================="<<endl;int i;for(i=0;i<8;i++) //输出算符优先矩阵{for(int j=0;j<8;j++){if(XX[i][j]=='!')cout<<"**"<<'\t';elsecout<<XX[i][j]<<'\t';}cout<<endl;}char in[maxsize]; //用于接收输入文件名char str[maxsize];//存句子FILE *fin; //用于指向输入文件的指针cout<<"请输入所需文件名(xxx.txt):";cin>>in;while((fin=fopen(in,"r"))==NULL) //判断输入文件名是否正确{cout<<endl<<"打开词法分析输入文件出错!"<<endl;cout<<"请重新输入:";strcpy(in,"");cin>>in;}int m=0;//记录str句子串的长度char ch1='a';while (ch1!='#')//从文件中读入一串字符{ch1=getc(fin);str[m++]=ch1;}str[m]='#';//将'#'赋给字符串尾Stack s;//定义Stack类的变量sint len;len=int(strlen(str));//取出输入字符串的长度s.push('#');//先把'#'压入数组array[]int k=s.getsize()-1;//k为当前数组array[]读入已读入字符的位置标识,int t=0;//t为输入字符串数组str[]即将被读的字符位置标识,int j;//j用于记录当前数组array[]中的最后一个非终结符的位置char a=str[0];//a用于传递即将读入的字符char ch[10];//存规约串while(a!='#')//如果a不等于'#',则继续读入操作或规约操作{a=str[t];if(a=='*'){if(str[t+1]=='*'){a='!';t++;}}if(isvt(s.judge(k)))j=k;elsej=k-1;while(isvt(a)&&getrank(s.judge(j),a)==1)//判断是否满足规约的条件>{s.disp_all();//规约后输出当前数组array[]中的字符int h=j,low=j-1;//h记录要规约的位置,low记录规约后数组array[]中的最qian一个非终结符的位置if(!isvt(s.judge(low)))low--;while(getrank(s.judge(low),s.judge(h))!=-1)//寻找最前一个非终结符的位置用low记录{h=low;low--;if(!isvt(s.judge(low)))low--;}h=s.getsize();//array的长度low++;//规约的起始位置int len=h-low; //len记录要规约的长度for(int p=0;p<10;p++)ch[p]='\0';s.pop(ch,len);//弹出要规约的字符用字符串ch存储char c=guiyue(ch);//将ch规约为Ns.push(c);//再将规约后的N压入数组中cout<<" 规约: ";for(i=0;i<strlen(ch);i++){if(ch[i]=='!')cout<<"**";elsecout<<ch[i];}cout<<" --> "<<guiyue(ch)<<endl;j=s.getsize()-1;if(!isvt(s.judge(j)))j--;}// s.disp_all();if(!(a>='A'&&a<='Z')&&getrank(s.judge(j),a)==2)//当待输入字符不是大写字母且与前一个{ //非终结符无优先关系则提示出错并给出提示cout<<"出错!"<<endl;cout<<"错误为第"<<t+1<<"个字符:"<<str[t]<<endl;exit(0);}else{s.disp_all();if(a=='!')cout<<"移进: **"<<endl;elsecout<<"移进: "<<a<<endl;s.push(a);//将a压入数组array[]//读入后输出当前数组array[]中的字符t++;k=s.getsize()-1;}}s.disp_all();char temp[10];s.pop(temp,3);if(s.getsize()==0)//如果最后数组array[]的长度size的值为0,则分析成功cout<<"成功!"<<endl;else//否则,分析失败cout<<"失败!"<<endl;fclose(fin);//关闭输入文件}3.基于算符优先分析方法的语法制导翻译程序的设计#include<string.h>#include<stdlib.h>#include <ctype.h>#include<iostream>using namespace std;typedef class Four *C;char XX[8][8]={' ','+','*','!','i','(',')','#','+','>','<','<','<','<','>','>','*','>','>','<','<','<','>','>','!','>','>','<','<','<','>','>','i','>','>','>',' ',' ','>','>','(','<','<','<','<','<','=',' ',')','>','>','>',' ',' ','>','>','#','<','<','<','<','<',' ','='};const int maxsize=100; //为数组str[]、in[]分配的最大存储空间const int length=100;//为数组array[]分配的最大存储空间int digital[maxsize];int d_len=0;char B[21];//标识符,b[0]记录最后一个的下标int E[21];//临时变量,e[0]记录最后一个的下标,1xx为标识符地址,2xx为临时变量地址C Gama[21];//一个中间变量即一个四元式,gama[i]记录最后一个下标int a=0,b=0,c=0;//B,E,Gama的最后一个下标int ATD(char ch);//将单个字符转为为数字int entry(char ch);//查找ch是否在名字表内,返回名字表内的下标+100,如没有则将其加入表中----------okint newtemp(int t[3]);//新建一个临时变量,返回其在临变表中的下标+200void fuzhi(int m,int n);//m.place:=n.placeint guiyue(int ch[],int ll);//规约为'N'int getrank(int i,int j);//根据算符优先分析矩阵设置读入优先次序int isword(char ch);//判断是否为字母//////////////////////////gai!!void disp_one(int i);//输出单个i代码的字符,标识符或符号void disp_deep_one(int i);//输出单个i代码的字符,标识符或符号typedef class Four//四元式{char fuhao;//int s2,s3,s4;//(fuhao,s2,s3,s4)public:Four(int f,int a1,int a2)//双目运算符,本题只有双目运算符...a1,a2均为地址位移量{fuhao=XX[0][f];s2=a1;s3=a2;s4=c+300;}void disp_four(){cout<<"产生"<<c<<": (";if(fuhao=='!')cout<<"**,";elsecout<<fuhao<<",";disp_deep_one(s2);cout<<",";disp_deep_one(s3);cout<<",";disp_deep_one(s4);cout<<")";}void disp_simple(){cout<<"(";if(fuhao=='!')cout<<"**,";elsecout<<fuhao<<",";disp_deep_one(s2);cout<<",";disp_deep_one(s3);cout<<",";disp_deep_one(s4);cout<<")"<<endl;}}*C;class stack{private:int size;//size为当前数组array[]的大小int array[length];//用于存储读入的字符public:stack(){size=0;//数组array[]的初始长度为0}void push(int ch)//将ch压入array[]{if(size<length)//如果数组未满,则压入{array[size]=ch;size++;}else//若数组已满,则给出出错信息cout<<"overflow! push error!"<<endl;}int pop(int ch[],int len)//弹出字符准备规约,返回弹出的字符个数{if(size-len>=0){for(int i=0;i<len;i++)ch[i]=array[size-len+i];size-=len;return len;}else{cout<<"参数错误!pop error!"<<endl;exit(0);}}int getone(int pos)//判断是否可以取数,并返回array[pos]{if(pos>=0&&pos<size)return array[pos];return 0;}void disp_all()//输出当前数组中的所有字符=====================改改改!{for(int i=0;i<size;i++)disp_one(array[i]);if(size>7)cout<<'\t'<<'\t';elsecout<<'\t'<<'\t'<<'\t';}int getsize()//返回当前数组大小{return size;}};stack s;//定义stack类的变量sint entry(char ch)//查找ch是否在名字表内,返回名字表内的下标+100,如没有则将其加入表中----------ok{for(int i=1;i<=B[0];i++)if(B[i]==ch)return i+100;B[++a]=ch;return a+100;}int newtemp(int t[3])//新建一个中间变量,返回其在临变表中的下标+300{c++;Gama[c]=new Four(t[1],t[0],t[2]);Gama[c]->disp_four();cout<<endl;return c+300;}int guiyue(int ch[],int ll)//规约为E/T,返回其地址值{s.pop(ch,ll);if(ll==1){E[++b]=ch[0];cout<<"规约:";disp_one(ch[0]);cout<<"==>";disp_one(b+200);cout<<endl;return b+200;}else if(ch[0]==5&&ch[2]==6)//(。

相关文档
最新文档