合肥工业大学编译原理实验报告(完整代码版)

合集下载

编译原理实验报告:实验一编写词法分析程序.

编译原理实验报告:实验一编写词法分析程序.

编译原理实验报告实验名称:实验一编写词法分析程序实验类型:验证型实验指导教师:何中胜专业班级:13软件四姓名:丁越学号:13030504电子邮箱:862245792@实验地点:秋白楼B720实验成绩:日期:2016年3 月18 日一、实验目的通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。

掌握文法转换成自动机的技术及有穷自动机实现的方法。

确定词法分析器的输出形式及标识符与关键字的区分方法。

加深对课堂教学的理解;提高词法分析方法的实践能力。

通过本实验,应达到以下目标:1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。

2、掌握词法分析的实现方法。

3、上机调试编出的词法分析程序。

二、实验过程以编写PASCAL子集的词法分析程序为例1.理论部分(1)主程序设计考虑主程序的说明部分为各种表格和变量安排空间。

数组 k为关键字表,每个数组元素存放一个关键字。

采用定长的方式,较短的关键字后面补空格。

P数组存放分界符。

为了简单起见,分界符、算术运算符和关系运算符都放在 p表中(编程时,还应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。

id和ci数组分别存放标识符和常数。

instring数组为输入源程序的单词缓存。

outtoken记录为输出内部表示缓存。

还有一些为造表填表设置的变量。

主程序开始后,先以人工方式输入关键字,造 k表;再输入分界符等造p表。

主程序的工作部分设计成便于调试的循环结构。

每个循环处理一个单词;接收键盘上送来的一个单词;调用词法分析过程;输出每个单词的内部码。

⑵词法分析过程考虑将词法分析程序设计成独立一遍扫描源程序的结构。

其流程图见图1-1。

图1-1该过程取名为 lexical,它根据输入单词的第一个字符(有时还需读第二个字符),判断单词类,产生类号:以字符 k表示关键字;i表示标识符;c表示常数;p表示分界符;s表示运算符(编程时类号分别为 1,2,3,4,5)。

编译原理实验报告_15

编译原理实验报告_15

编译原理实验报告实验一词法分析器的设计与实现 (1)1)实验目的 (1)2)实验内容 (1)3)实验要求 (1)4)实验原理 (1)5)实验步骤 (1)6)状态转化图及词法分析程序 (2)7)测试 (7)实验二语法分析器的设计与实现 (9)1)实验目的 (9)2)实验内容 (9)3)实验要求 (9)4)实验原理 (9)5)实验步骤 (9)6)语法分析程序 (10)7)测试 (16)编译原理实验报告专业:计算机科学与技术学生姓名:学号: 48完成时间:2020年11月25日实验一词法分析器的设计与实现1)实验目的①掌握正规式、状态转换图、C语言单词符号的划分及词法分析器的实现②掌握词法分析程序的作用和接口。

2)实验内容设计及实现C语言程序的词法分析器。

3)实验要求①对任给的一个C语言源程序,能够虑掉空格、回车换行符、tab键及注释。

②识别各类单词符号,如关键字、标识符、运算符、常数、界符,结果以二元式形式输出。

并构造符号表。

③输出有词法错误的单词及所在行号。

4)实验原理根据扫描到的单词符号的第一个字符的种类,分别转到相应的程序进行处理。

这些程序的功能就是识别以相应字符开头的各类单词符号。

5)实验步骤①根据C语言各类单词的正规式,构造能识别各类单词的状态转换图。

②根据状态转换图,构造识别各类单词的词法分析器。

6)状态转化图及词法分析程序#include ""#include ""#include ""FILE *fp;int id;void main(){char cbuffer;char alphaprocess(char buffer);char digitprocess(char buffer);char otherprocess(char buffer);if ((fp=fopen("","r"))==NULL) /*以只读方式打开文件"",NULL在文件中已被定义为0*/printf("error");else{cbuffer=fgetc(fp); /*文件不为空则从文件中取字符*/while (cbuffer!=EOF) /*EOF文件结束标志*/{if(cbuffer==' '||cbuffer=='\n') /*掠过空格和回车符*/{cbuffer=fgetc(fp);id=4;}else if(isalpha(cbuffer))cbuffer=alphaprocess(cbuffer); /*检查cbuffer是否为字母,是则调用alphaprocess()函数*/else if (isdigit(cbuffer))cbuffer=digitprocess(cbuffer); /*检查cbuffer是否为数字0~9,是则调用digitprocess()函数*/else cbuffer=otherprocess(cbuffer); /*非上述两者则调用otherprocess()函数*/}}}char alphaprocess(char buffer){int search(char searchchar[],int wordtype); /*函数声明*/int atype;int i=-1;char alphatp[20]; /*字符数组存储从文件中读取的字符*/while((isalpha(buffer))||(isdigit(buffer))||buffer=='_') /*标识符的组成成分*/{alphatp[++i]=buffer; /*将当前读取的字符存如数组*/buffer=fgetc(fp); /*读取下一个字符*/}alphatp[i+1]='\0'; /*字符串以'\0'作为结束标志*/atype=search(alphatp,1); /*调用函数,判断当前字符串是否为关键字*/if(atype!=0) /*是关键字则输出该关键字,编号为1,并输出该关键字在关键字表中的位子*/{printf("(%s, (1,%d))\n",alphatp,atype);id=1; /*关键字的ID为1*/}else{printf("(%s ,2)\n",alphatp); /*为标识符时,编号为2*/id=2; /*标识符的ID为2*/}return(buffer);}/*判断字符串是否为关键字*/int search(char searchchar[],int wordtype){char * key[32]={"auto","break","case","char","const","continue","default","d o", "double","else","enum","extern","float","for","goto","if","int","long ", "register","return","short","signed","sizeof","static","struct", "volatile","while","switch","typedef","union","unsigned","void"};/*设置数组指针存储c语言中的32个关键字*/int i;int p;switch (wordtype){case 1:for (i=0;i{if (strcmp(key[i],searchchar)==0) /*比较字符串,为关键字则定位该关键字的序号*/{ p=i+1; break; }else p=0;}return(p);}}char digitprocess(char buffer){int i=-1;char digittp[20];while ((isdigit(buffer))||buffer=='.'||buffer=='e'||buffer=='E')//考虑数字为小数和指数时的情况{digittp[++i]=buffer;buffer=fgetc(fp); /*同上*/}digittp[i+1]='\0';printf("(%s ,3)\n",digittp); /*输出该数字,编号为3*/ id=3; /*设置ID 为3*/return(buffer);}char otherprocess(char buffer){int n=0;char ch[20];ch[0]=buffer;ch[1]='\0';if(ch[0]=='%'||ch[0]=='\\'){ buffer=fgetc(fp);ch[1]=buffer;ch[2]='\0';printf("(%s ,5)\n",ch);id=4;buffer=fgetc(fp);return(buffer);}if(ch[0]=='&'){buffer=fgetc(fp);if(buffer!='&')printf("(%s ,5)\n",ch);id=4;return(buffer);}if(buffer=='&'){ch[1]=buffer;ch[2]='\0';printf("(%s ,4)\n",ch);id=3;buffer=fgetc(fp);return(buffer);}}if(ch[0]==','||ch[0]==';'||ch[0]=='{'||ch[0]=='}'||ch[0]=='('||ch[0]= =')') {printf("(%s ,5)\n",ch);buffer=fgetc(fp);id=4;return(buffer);}if(ch[0]=='*'||ch[0]=='/')printf("(%s ,4)\n",ch);buffer=fgetc(fp);id=4;return(buffer);}if(ch[0]=='='||ch[0]=='!'||ch[0]==''){buffer=fgetc(fp);if(buffer=='=') /*防止'==','!=','='符号的分离*/ { ch[1]=buffer;ch[2]='\0';printf("(%s ,4)\n",ch);}else{printf("(%s ,4)\n",ch);id=4;return(buffer);}buffer=fgetc(fp);id=4;return(buffer);-全文完-。

编译原理实验报告总结

编译原理实验报告总结

学年第学期《编译原理》实验报告学院(系):计算机科学与工程学院班级:11303070A学号:***********姓名:无名氏指导教师:保密式时间:2016 年7 月目录1.实验目的 (1)2.实验内容及要求 (1)3.实验方案设计 (1)3.1 编译系统原理介绍 (1)3.1.1 编译程序介绍 (2)3.1.2 对所写编译程序的源语言的描述 (2)3.2 词法分析程序的设计 (3)3.3 语法分析程序设计 (4)3.4 语义分析和中间代码生成程序的设计 (4)4. 结果及测试分析 (4)4.1软件运行环境及限制 (4)4.2测试数据说明 (5)4.3运行结果及功能说明 (5)5.总结及心得体会 (7)1.实验目的根据Sample语言或者自定义的某种语言,设计该语言的编译前端。

包括词法分析,语法分析、语义分析及中间代码生成部分。

2.实验内容及要求(1)词法分析器输入源程序,输出对应的token表,符号表和词法错误信息。

按规则拼单词,并转换成二元形式;滤掉空白符,跳过注释、换行符及一些无用的符号;进行行列计数,用于指出出错的行列号,并复制出错部分;列表打印源程序;发现并定位词法错误;(2)语法分析器输入token串,通过语法分析,寻找其中的语法错误。

要求能实现Sample 语言或自定义语言中几种最常见的、基本的语法单位的分析:算术表达式、布尔表达式、赋值语句、if语句、for语句、while语句、do while语句等。

(3)语义分析和中间代码生成输入token串,进行语义分析,修改符号表,寻找其中的语义错误,并生成中间代码。

要求能实现Sample语言或自定义语言中几种最常见的、基本的语法单位的分析:算术表达式、布尔表达式、赋值语句、if语句、for语句、while 语句、do while语句等。

实验要求:功能相对完善,有输入、输出描述,有测试数据,并介绍不足。

3.实验方案设计3.1 编译系统原理介绍编译器逐行扫描高级语言程序源程序,编译的过程如下:(1).词法分析识别关键字、字面量、标识符(变量名、数据名)、运算符、注释行(给人看的,一般不处理)、特殊符号(续行、语句结束、数组)等六类符号,分别归类等待处理。

编译原理语法分析实验报告

编译原理语法分析实验报告
char data[20][20]; char s[100]; char lable[20]; char input[100]; char string[20][10]; int k; char a; int j; char q; int r; int r1; char st[10][30]; char first[10][10]; char last[10][10]; int fflag[10]={0}; FIRSTVT集是否已求出 int lflag[10]={0}; LASTVT集是否已求出 int deal(); int zhongjie(char c); int xiabiao(char c);
//输出转化后
的文法规则串
{
printf("%s\n",text[i]);
}
for(i=0;i<x;i++) /*求每个终结符的推导结果(去掉"->"后的转化文
法,用于最后的规约)*/
{ string[i][0]=text[i][0];
for(j=3,l=1;text[i][j]!='\0';j++,l++)
表1-2 G[S]的算符优先关系矩阵表
#
i
+
*
(
)
#
i
+
*
(
)
二.程序设计
1.总体设计
求FIRSTVT模块 求LASTVT模块 识别终结符模块
读入文法规则 创建文法关系表模块
求下标模块
2.子程序设计
识别终结符模块
读取语法分析串 输入串分析模块 图2-1 总体设计图
求FIRSTVT模块 求LASTVT模块

计算机编译原理实验报告

计算机编译原理实验报告

编译原理实验报告实验一词法分析设计一、实验功能:1、对输入的txt文件内的内容进行词法分析:2、由文件流输入test.txt中的内容,对文件中的各类字符进行词法分析3、打印出分析后的结果;二、程序结构描述:(源代码见附录)1、分别利用k[],s1[],s2[],s3[]构造关键字表,分界符表,算术运算符表和关系运算符表。

2、bool isletter(){} 用来判断其是否为字母,是则返回true,否则返回false;bool isdigit(){} 用来判断其是否为数字,是则返回true,否则返回false;bool iscalcu(){} 用来判断是否为算术运算符,是则返回true,否则返回false;bool reserve(string a[]){} 用来判断某字符是否在上述四个表中,是则返回true,否则返回false;void concat(){} 用来连接字符串;void getn(){} 用来读取字符;void getb(){} 用来对空格进行处理;void retract(){}某些必要的退格处理;int analysis(){} 对一个单词的单词种别进行具体判断;在主函数中用switch决定输出。

三、实验结果四、实验总结词法分析器一眼看上去很复杂,但深入的去做就会发现并没有一开始想象的那么困难。

对于一个字符的种别和类型可以用bool函数来判断,对于关键字和标示符的识别(尤其是3b)则费了一番功夫,最后对于常数的小数点问题处理更是麻烦。

另外,这个实验要设定好时候退格,否则将会导致字符漏读甚至造成字符重复读取。

我认为,这个实验在程序实现上大体不算困难,但在细节的处理上则需要好好地下功夫去想,否则最后的程序很可能会出现看上去没有问题,但实际上漏洞百出的状况。

将学过的知识应用到实际中并不简单,只有自己不断尝试将知识转化成程序才能避免眼高手低,对于知识的理解也必将更加深刻。

实验二LL(1)分析法一、实验原理:1、写出LL(1)分析法的思想:当一个文法满足LL(1)条件时,我们就可以为它构造一个不带回溯的自上而下的分析程序,这个分析程序是有一组递归过程组成的,每个过程对应文法的一个非终结符。

实验报告编译实验

实验报告编译实验

一、实验目的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)目标代码生成:编译器将优化后的中间代码转换成汇编代码。

合工大Java实验报告

实验报告课程名称:Java技术学生:学号:专业班级:指导教师:年月日实验一Java开发环境的安装与配置四、实验过程、步骤及原始记录(算法、原程序、测试结果,分析等)1.从.oracle./technetwork/java下载最新版本的JDK,并安装。

(或者用已有文件安装)安装过程:安装Jdk集成环境,安装成功后,配置path,classpath路径,让用户在任何目录下均可用到Java的系统资源①先配置%JA V A_HOME%环境变量,路径为jdk的目录;②配置path环境变量,路径为%JA V A_HOME%\bin;③再配置classpath环境变量路径为;%JA V A_HOME%\lib;%JA V A_HOME%\lib\tools.jar2.设置环境变量PATH, CLASSPATH, 使得Java程序能正确编译和执行。

3.在Textpad(JCreator或Eclipse)环境下编写一个HelloWorld.java程序,在DOS提示符下编译并执行这个程序。

实验过程:在Notepad++中写出如下代码,并保存为HelloWorld.java:源代码:public class HelloWorld {public static void main(String[] args) {System.out.println("Hello World!");}}在命令行中进入到该文件路径,并输入javac HelloWorld.java完成编译,再输入java HelloWorld完成运行运行结果:4.编写一个类A,它位于包a中,保存到A.java中,再编写一个类B,它位于包b中,保存到B.java中。

在类B中实例化类A的一个对象。

分别编译类A和类B。

实验过程:用Eclipse编写包 a 包 b 的程序,并用DOS 命令行运行。

源代码:A:package a;public class A {public void OUT() {System.out.println("this is a!");}}B:package b;import a.*;public class B {public static void main(String[] args) {A a = new A();a.OUT();}}运行结果:五、实验结论、分析、思考题与心得体会心得体会通过本次实验,我对于Java的一些基本知识有所了解,下面我将进行总结:1.我学习了如何安装JDK,以及配置JA V A环境2.我学习了使用Notepad++记事本环境下编写Java程序,并使用命令行来编译执行程序3.我学会了在Eclipse环境下编写与运行Java程序。

编译原理实验一代码

Scan.c#include"stdio.h"#include"ctype.h"#include"string.h"#include"tag.h"typedef enum{ENDF=1,ERROR=2,ID=3,NUM=4,RNUM=5,INT=6,REAL=7,MOD=8,ITOR=9, ADD=10,MUL=11,ASSIGN=12,SEMI=13,COMMA=14,LPAR=15,RPAR=16} Tag;#define MAXTOKENSIZE 9#define MAXCHILDERN 3typedef Tag TokenType;typedef Tag NodeKind;#endifint col,row;FILE *source;TokenType token;char tokenString[MAXTOKENSIZE];#define BUFSIZE 128static char buf[BUFSIZE]="\0";static char nextch(){if(col>=strlen(buf)){row++;if(fgets(buf,BUFSIZE-1,source)){col=0;return buf[col++];}return EOF;}return buf[col++];}static voi d retract(){col--;}#define MAXRESERVEWORDS 3struct {char* str;TokenType tok;}reserveword[MAXRESERVEWORDS]={ {"mod",MOD},{"int",INT},{"real",REAL}};static TokenType rsfind(char* s){int i;for(i=0;i<MAXRESERVEWORDS;i++) if(!strcmp(s,reserveword[i].str)){return reserveword[i].tok;}return ID;}static voi d id(char ch){int i=0;tokenString[i++]=ch;while(isalpha(ch=nextch()))if(i<MAXTOKENSIZE-1)tokenString[i++]=ch;retract();tokenString[i]='\0';token=rsfind(tokenString);if(token!=ID) tokenString[0]=0;}static voi d num(char ch){int i=0;tokenString[i++]=ch;while(isdigit(ch=nextch()))if(i<MAXTOKENSIZE-1)tokenString[i++]=ch;if(ch!='.'){retract();tokenString[i]='\0';token=NUM;}else{tokenString[i++]=ch;while(isdigit(ch=nextch()))if(i<MAXTOKENSIZE-1)tokenString[i++]=ch;retract();tokenString[i]='\0';token=RNUM;}}void tkget(){char ch;strcpy(tokenString,"\0");while(isspace(ch=nextch()));if(isdigit(ch)){num(ch);}else if(isalpha(ch)){id(ch);}else if(ch==EOF){token=ENDF;}else{switch(ch){case'+':token=ADD;break;case'*':token=MUL;break;case';':token=SEMI;break;case',':token=COMMA;break;case'(':token=LPAR;break;case')':token=RPAR;break;case'=':token=ASSIGN;break;default:token=ERROR;break;}}}#include"stdio.h"#include"tree.h"int main(int arge,char*argv[0]){ extern Tree root;extern File*source;source=fopen(argv[1],"r");root=(Tree)parse();trseq(root);trput(stdout,root);stput(stdout);}。

合工大Java实验报告

实验报告课程名称:Java技术学生:学号:专业班级:指导教师:年月日实验一Java开发环境的安装与配置四、实验过程、步骤及原始记录(算法、原程序、测试结果,分析等)1.从.oracle./technetwork/java下载最新版本的JDK,并安装。

(或者用已有文件安装)安装过程:安装Jdk集成环境,安装成功后,配置path,classpath路径,让用户在任何目录下均可用到Java的系统资源①先配置%JA V A_HOME%环境变量,路径为jdk的目录;②配置path环境变量,路径为%JA V A_HOME%\bin;③再配置classpath环境变量路径为;%JA V A_HOME%\lib;%JA V A_HOME%\lib\tools.jar2.设置环境变量PATH, CLASSPATH, 使得Java程序能正确编译和执行。

3.在Textpad(JCreator或Eclipse)环境下编写一个HelloWorld.java程序,在DOS提示符下编译并执行这个程序。

实验过程:在Notepad++中写出如下代码,并保存为HelloWorld.java:源代码:public class HelloWorld {public static void main(String[] args) {System.out.println("Hello World!");}}在命令行中进入到该文件路径,并输入javac HelloWorld.java完成编译,再输入java HelloWorld完成运行运行结果:4.编写一个类A,它位于包a中,保存到A.java中,再编写一个类B,它位于包b中,保存到B.java中。

在类B中实例化类A的一个对象。

分别编译类A和类B。

实验过程:用Eclipse编写包 a 包 b 的程序,并用DOS 命令行运行。

源代码:A:package a;public class A {public void OUT() {System.out.println("this is a!");}}B:package b;import a.*;public class B {public static void main(String[] args) {A a = new A();a.OUT();}}运行结果:五、实验结论、分析、思考题与心得体会心得体会通过本次实验,我对于Java的一些基本知识有所了解,下面我将进行总结:1.我学习了如何安装JDK,以及配置JA V A环境2.我学习了使用Notepad++记事本环境下编写Java程序,并使用命令行来编译执行程序3.我学会了在Eclipse环境下编写与运行Java程序。

编译原理实验报告

<<编译原理>>上机实验报告编译原理上机实验报告一、实验目的与要求目的:在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。

达到进一步了解程序编译过程的基本原理和基本实现方法的目的。

要求:对PL/0作以下修改扩充基本内容:增加单词:保留字ELSE,FOR,TO,DOWNTO,RETURN运算符+=,-=,++,--修改单词:不等号# 改为<>增加条件语句的ELSE子句实验环境与工具(1)计算机及操作系统:PC机,WindowsXP(2)程序设计语言:C++Builder6(3)教学型编译程序:PL/0二、设计方案1)概述:编译程序编绎的源程序是PL0,程序产生的目标代码是一个假想栈式计算机的汇编语言.称为类PCODE指令代码 ,指令格式格式如下:其中F代表功能码,L表示层次差,A表示位移量,不同指令其含义有所区别。

PL/0语言是Pascal语言的一个子集,这里分析的PL/0的编译程序包括了对PL/0语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。

PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。

词法分析和代码生成作为独立的子程序供语法分析程序调用。

语法分析的同时,提供了出错报告和出错恢复的功能。

在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE 代码。

编译器实现工具和运行平台程序用C++语言编写,在C++ Builder平台下运行。

2)结构设计说明:PL/0的编译过程采用一趟扫描方式,以语法分析为核心,词法分析程序和代码生成程序都作为一个独立的过程,当语法分析需要读入单词时就调用词法分析程序,而当语法分析正确需生成相应的目标代码时,则调用代码生成程序。

此外,用表格管理程序建立变量、常量和过程标识符的说明与引用之间的信息联系。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

. . 计算机与信息学院 编译原理 实验报告

专 业 班 级 信息安全13-1班

学生及学号 马骏 2013211869

课程教学班号

任 课 教 师 宏芒

实验指导教师 宏芒

实验地点 实验楼机房

2015 ~2016 学年第 二 学期 .

. 实验1 词法分析设计 一、 实验目的 通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设 计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的 理解,并能正确地、熟练地运用 二、 实验要求 1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。 3、根据测试数据进行测试。测试实例应包括以下三个部分: 全部合法的输入。 各种组合的非法输入。 由记号组成的句子。 4、词法分析程序设计要求输出形式: 例:输入VC++语言的实例程序: If i=0 then n++; a﹤= 3b %); 输出形式为: 单词 二元序列 类 型 位置(行,列) (单词种别,单词属性) for (1,for ) 关键字 (1,. . 1) i ( 6,i ) 标识符 (1,2) = ( 4,= ) 关系运算符 (1,3) 12 0 ( 5,0 ) 常数 (1,4) then ( 1,then) 关键字 (1,5) n (6,n ) 标识符 (1,6) ++ Error Error (1,7) ; ( 2, ; ) 分界符 (1,8) a (6,a ) 标识符 (2,1) ﹤= (4,<= ) 关系运算符 (2,2) 3b Error Error (2,4) % Error Error (2,4) ) ( 2, ) ) 分界符 (2,5) ; ( 2, ; ) 分界符 (2,6) 三、 实验容 用 VC++/VB/JAVA 语言实现对 C 语言子集的源程序进行词法分析。通过. . 输 入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的部编码及单 词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示 ;同时 进行标识符登记符号表的管理。 以下是实现词法分析设计的主要工作: (1)从源程序文件中读入字符。 (2)统计行数和列数用于错误单词的定位。 (3)删除空格类字符,包括回车、制表符空格。 (4)按拼写单词,并用(码,属性)二元式表示。(属性值——token的机 表示) (5)如果发现错误则报告出错 7 (6)根据需要是否填写标识符表供以后各阶段使用。

四、实验步骤 1、根据流程图编写出各个模块的源程序代码上机调试。 2、 编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计 的词法分析程序;直至能够得到完全满意的结果。 3、书写实验报告 ;实验报告正文的容: 功能描述:该程序具有什么功能? 程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数 . . 之间的调用关系图。 详细的算法描述(程序总体执行流程图) 。 给出软件的测试方法和测试结果。 实验总结 (设计的特点、不足、收获与体会)。 五、实验截图 先创建salaryfile.txt文件 输入 If i=0 then n++; a<= 3b %);

六、核心代码 #include #include #include #include using namespace std;

const char* salaryfile="salaryfile.txt"; . . const int max=40; string id[max]={"do","end","for","if","printf","scanf","then","while"};//关键字表 string s[max]={",",";","(",")","[","]","+","-","*","/","<","<=","=",">",">=","<>"};//分界符表 算数运算符表 关系运算符表 string k[max];// 标识符 string ci[max];// 常数 int fjfpoint=5;//分界符表尾 int mathpoint=9;//算数运算符表尾 int cipointer=0;//常数表尾 int idpointer=0;//关键字表尾 int kpointer=0;//标识符表尾 int fjf;//0 不是分界符 1是

int rowy=1;//识别输入行位置 int rowx=1;//识别输入列位置

int outkey=0;//打印控制 0为数字后有字母 其他可以 void searcht(int i,string m)//根据已识别的首字母识别字符串 { . . // cout<<"enter searcht!!"

} }

} if(i==1)//识别常数 { // cout<<" a number!!"

cout<<"(5,"

} if(x>5&&x<10) { if(outkey==1) { cout<<"(3,"<("< outkey=0; } fjf=0; } if(x>9&&x{ if(outkey==1) { cout<<"(4,"<("< outkey=0; } fjf=0; . . } if(x==max) { if(outkey==1) { cout<<"Error Error ("

};

void wordlook(char t,string sn)//识别首字符,分类识别字符串 { if(t>=48&&t<=57) searcht(1,sn); else { if((t>64&&t<91)||(t>96&&t<123)) searcht(0,sn); . . else searcht(2,sn); }

}; void split(string s)//分割字符串 { // cout

int i=0; int x; int sign=2;//非法数字标志 int diannumber=0;//数中点的个数

for(x=0;x{

if((s[x]>64&&s[x]<91)||(s[x]>96&&s[x]<123)||(s[x]>=48&&s[x]<=57)||(x>0&&s[x]==46&&sign==1))//判断数字后跟字母还是字母后有数字 {

相关文档
最新文档