实验一 源程序的预处理及词法分析程序设计
源程序的预处理--编译原理实验1教案资料
![源程序的预处理--编译原理实验1教案资料](https://img.taocdn.com/s3/m/f477ec517375a417866f8fb8.png)
深圳大学实验报告课程名称:编译原理实验名称:源程序的预处理姓名:学号:班级:实验日期:第2周实验课、第4周实验课一. 实验目的1) 编写简单的词法分析程序;二. 实验环境1) 硬件环境:计算机;2) 软件环境:C/C++编译器;三. 实验内容1. 用C或C++语言编写一个简单的词法分析程序,能够删除C/C++源程序中的所有注释,并输出处理后的结果。
例如,下面的C/C++源程序中的绿色部分都表示注释。
#include<iostream>using namespace std;void main(){//this is a single line comment/*this is a multiline comment*/cout<<"hello world"<<endl;/*this is a multiline comment/*this is a multiline comment*/cout<<"this is not a comment"<<endl;*/cout<<"/*this is not a comment*/"<<endl;//*cout<<"this is not a comment"<<endl;*/}要求输出:#include<iostream>using namespace std;void main(){cout<<"hello world"<<endl;cout<<"this is not a comment"<<endl;*/cout<<"/*this is not a comment*/"<<endl;cout<<"this is not a comment"<<endl;*/}直接在实验报告中粘贴程序代码,并提供几个实验结果的截图(对窗口截图时先同时按alt 和prtscn键,再按ctrl+v粘贴)。
词法分析实验报告代码
![词法分析实验报告代码](https://img.taocdn.com/s3/m/1b699ab3afaad1f34693daef5ef7ba0d4b736d49.png)
一、实验目的1. 理解词法分析的概念和作用。
2. 掌握词法分析器的设计和实现方法。
3. 通过实验加深对编译原理中词法分析阶段的理解。
二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容1. 设计一个简单的词法分析器,能够识别并输出源代码中的单词。
2. 实现词法分析器的关键功能,包括:- 字符串预处理- 单词识别- 生成词法分析表四、实验步骤1. 字符串预处理- 读取源代码字符串。
- 移除字符串中的空白字符(空格、制表符、换行符等)。
- 转义字符串中的特殊字符。
2. 单词识别- 使用正则表达式匹配单词。
- 根据正则表达式匹配结果,将单词分类为关键字、标识符、常量等。
3. 生成词法分析表- 创建一个列表,用于存储词法分析表中的每个单词及其对应的类别。
- 遍历源代码字符串,将识别出的单词添加到词法分析表中。
五、实验代码```pythonimport re# 定义词法分析表结构class Token:def __init__(self, type, value):self.type = typeself.value = value# 单词识别函数def tokenize(source_code):# 移除空白字符source_code = re.sub(r'\s+', '', source_code)# 转义特殊字符source_code = re.sub(r'\\', '\\\\', source_code)# 使用正则表达式匹配单词tokens = re.findall(r'\b\w+\b', source_code)# 生成词法分析表token_table = []for token in tokens:if re.match(r'\bint\b', token):token_table.append(Token('KEYWORD', token))elif re.match(r'\bfloat\b', token):token_table.append(Token('KEYWORD', token))elif re.match(r'\bchar\b', token):token_table.append(Token('KEYWORD', token))elif re.match(r'\bif\b', token):token_table.append(Token('KEYWORD', token))elif re.match(r'\belse\b', token):token_table.append(Token('KEYWORD', token))elif re.match(r'\breturn\b', token):token_table.append(Token('KEYWORD', token))elif re.match(r'\b\w+\b', token):token_table.append(Token('IDENTIFIER', token)) else:token_table.append(Token('CONSTANT', token)) return token_table# 主函数def main():# 读取源代码source_code = '''int main() {int a = 10;float b = 3.14;char c = 'A';if (a > b) {return a;} else {return b;}}'''# 进行词法分析token_table = tokenize(source_code)# 输出词法分析结果for token in token_table:print(f'Type: {token.type}, Value: {token.value}') if __name__ == '__main__':main()```六、实验结果运行实验代码后,输出如下:```Type: KEYWORD, Value: intType: IDENTIFIER, Value: mainType: KEYWORD, Value: (Type: KEYWORD, Value: )Type: KEYWORD, Value: intType: IDENTIFIER, Value: a Type: KEYWORD, Value: = Type: CONSTANT, Value: 10 Type: KEYWORD, Value: ; Type: KEYWORD, Value: float Type: IDENTIFIER, Value: b Type: KEYWORD, Value: = Type: CONSTANT, Value: 3.14 Type: KEYWORD, Value: ; Type: KEYWORD, Value: char Type: IDENTIFIER, Value: c Type: KEYWORD, Value: = Type: CONSTANT, Value: A Type: KEYWORD, Value: ; Type: KEYWORD, Value: if Type: IDENTIFIER, Value: ( Type: IDENTIFIER, Value: a Type: KEYWORD, Value: > Type: IDENTIFIER, Value: b Type: KEYWORD, Value: ) Type: KEYWORD, Value: { Type: KEYWORD, Value: return Type: IDENTIFIER, Value: aType: KEYWORD, Value: ;Type: KEYWORD, Value: }Type: KEYWORD, Value: elseType: KEYWORD, Value: {Type: KEYWORD, Value: returnType: IDENTIFIER, Value: bType: KEYWORD, Value: ;Type: KEYWORD, Value: }```七、实验总结通过本次实验,我们成功地设计并实现了一个简单的词法分析器,能够识别并输出源代码中的单词。
编译实验1 编写词法分析程序
![编译实验1 编写词法分析程序](https://img.taocdn.com/s3/m/c2dcd76f0b4c2e3f56276319.png)
实验1:编写词法分析程序
本实验进行词法分析程序的编程与调试。
1 实验类型
验证型实验。
2 实验目的和要求
通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析程序所用的工具自动机,进一步理解自动机理论。
掌握文法转换成自动机的技术及有穷自动机实现的方法。
确定词法分析器的输出形式及标识符与关键字的区分方法。
加深对课堂教学的理解;提高词法分析方法的实践能力。
通过本实验,应达到以下目标:
1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。
2、掌握词法分析的实现方法。
3、上机调试编出的词法分析程序。
3 背景知识
词法分析是作为相对独立的阶段来完成的(对源程序或中间结果从头到尾扫描一次,并作相应的加工处理,生成新的中间结果或目标程序)。
在词法分析过程中,编译程序是通过操作系统从外部介质中读取源程序文件中的各个字符的。
同时,为正确地识别单词,有时还需进行超前搜索和回退字符等操作。
因此,为了提高读盘效率和便于扫描器进行工作,通常可采用缓冲输入的方案,即在内存中设置一个适当大小的输入缓冲区,让操作系统直接将磁盘上的源程序字符串分批送入此缓冲区中,供扫描器进行处理。
词法分析程序的一般设计方案是:
1、词法规则⇒正规表达式⇒FA;
2、NFA 确定化⇒DFA;
3、最小化DFA;
4、确定单词符号输出形式;
5、构造词法分析程序。
4 实验
设计一个程序,可以实现任意正则式的最小化DFA二维表输出,并能进行单词的识别和输出。
实验一实现简单词法分析器实验内容
![实验一实现简单词法分析器实验内容](https://img.taocdn.com/s3/m/50e589da0912a21615792963.png)
实验一实现简单词法分析器实验内容实验一实现简单的词法分析器一、实验内容实现一个C语言子集的词法分析程序。
二、实验要求1、要求能识别整数、自定义标识符及以下关键字:+-*/===!==||=()[]{}:;,voidintfloatcharifelsewhiledo!main2、自己任意书写一小段包含上述部分关键字的C语言代码,编写词法分析程序分析所写的代码,可以用任何语言实现,输出程序中所有关键字、整数、自定义标识符对应的二元式。
3、关键字、自定义标识符、整数的类号自己确定,要求将确定的类号以表格的形式书写在纸质实验报告上。
4、要求输出的格式是:假设float的类号是28,则识别float的输出结果是(float,28);对于整数与自定义标识符,假设标识符的类号是1,则识别标识符的输出结果是(标识符名称,1),同时将该标识符放入一张符号表。
5、实例如下:三、提示1、程序代码提交给课代表。
2、纸质实验报告内容:实验内容、自己写的待扫描的C语言源程序,类号分配表,所实现代码的核心代码,词法分析结果。
实验指导一、实验涉及的数据结构与变量1、关键字列表struct{charsymbol[30];intclassID;}keywordtable[33];用于存放实验要求的33个关键字,可以在定义该结构数组时直接初始化,给每个关键字分配唯一的类号。
2、符号表struct{charname[20];inttype;}symtable[100];用于存放源程序中的自定义标识符与整数(不考虑浮点数),其中整数的类号与自定义标识符的类号自行确定,但是不能与关键字的类号相同。
3、二元式列表struct{charsign[20];intclassID;}eryuanshi[100];用于存放所有识别的二元式,包含关键字、整数、自定义标识符。
4、几个变量intkey_count=33;//关键字的个数intsym_count;//符号表计数器interyuanshi_count;//二元式计数器二、实验涉及的函数1、voidlookup(char*p)【功能说明】首先在关键字列表keywordtable中查询字符串p,若存在就将该字符串及对应的类号插入二元式列表eryuanshi;若没有,在符号表symtable中查询,如果symtable中不存在p就将p插入,这里要分p 是标识符还是整数区别对待,设置不同的type值。
实验安排+词法分析程序设计与实现
![实验安排+词法分析程序设计与实现](https://img.taocdn.com/s3/m/512a63bbfd0a79563c1e72ef.png)
实验一词法分析程序设计与实现一、实验目的:加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。
二、实验内容:自定义一种程序设计语言,或者选择已有的一种高级语言(C语言),编制它的词法分析程序。
词法分析程序的实现可以采用任何一种编程工具。
三、实验要求:1. 对单词的构词规则有明确的定义;2. 编写的分析程序能够正确识别源程序中的单词符号;3. 识别出的单词以<种别码,值>的形式保存在符号表中;4. 词法分析中源程序的输入以.c格式,分析后的符号表保存在.txt文件中。
5. *对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成整个源程序的词法分析;6. 实验报告要求用自动机或者文法的形式对词法定义做出详细说明,说明词法分析程序的工作过程,说明错误处理的实现*。
四、实验学时:6学时五、实验步骤:1. 定义目标语言的可用符号表和构词规则;2. 依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结束;3. 对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中;4. *对不正确的单词,做出错误处理*。
六、选作实验学生可以根据自身的情况完善词法分析程序的错误处理功能(实验要求5&6),如对错误的单词给出准确的位置和错误类型提示。
七、作业提交时间第8周实验课结束后提交词法分析程序(zzwyanqiu@)。
八、提示1. char Scanin[100],Scanout[100]; //用于接收输入输出文件名FILE *fin,*fout; //用于指向输入输出文件的指针2. //下面定义保留,为简化程序,使用字符指针数组保存所有保留字。
//如果想增加保留字,可继续添加,并修改保留字数目#define keywordSum 8char *keyword[keywordSum]={ "if","else","for","while","do","int","read","write"};3. //下面定义纯单分界符,如需要可添加char singleword[50]="+-*(){};,:";4. //下面定义双分界符的首字符char doubleword[10]="><=!";5. scanf("%s",Scanin);printf("请输入词法分析输出文件名(包括路径):");scanf("%s",Scanout);6. if ((fin=fopen(Scanin,"r"))==NULL) //判断输入文件名是否正确{printf("\n打开词法分析输入文件出错!\n");return(1);//输入文件出错返回错误代码1}if ((fout=fopen(Scanout,"w"))==NULL) //判断输出文件名是否正确{printf("\n创建词法分析输出文件出错!\n");return(2); //输出文件出错返回错误代码2}7. ch=getc(fin);//读取文件里的一个字符8. isalpha(ch) //字母判断函数isalnum(ch)) //数字判断函数strcmp(token,keyword[n]) //串比较fprintf(fout,"%s\t%s\n","ID",token); //输出标识符符号到fout指定的文件strchr(singleword,ch) //声明: char *strchr( const char *string, int c );//在字符串string中搜索字符c,若成功则返回一个指向该字符第一次出现的位置,否则返回NULL//这个例子中的变量x的值为5:char string[]="hello"; char *p; int x; p=strchr(string,'o'); x=p-string+1; /tenax/clib/clib.html //c库函数查找地址任务1:识别小型语言所有单词的词法分析程序设计源程序设计语言G[<程序>]<程序>→<变量说明><BEGIN> <语句表> <END>.<变量说明>→VAR<变量表>:<类型>;|<空><变量表>→<变量表>,<变量>|<变量><类型>→INTEGER<语句表>→<语句> | <语句>;<语句表><语句>→<赋值语句>|<条件语句>|<WHILE语句>|<复合语句><赋值语句>→<变量>:=<算术表达式><条件语句>→IF<关系表达式>THEN<语句>ELSE<语句><WHILE语句>→WHILE<关系表达式>DO<语句><复合语句>→BEGIN<语句表>END<算术表达式>→<项>|<算术表达式>+<项>|<算术表达式>-<项><项>→<因式>|<项>*<因式>|<项>/<因式><因式>→<变量>|<整数>|(<算术表达式>)<关系表达式>→<算术表达式><关系符><算术表达式><变量>→<标识符><标识符>→<标识符><字母>|<标识符><数字>|<字母><整数>→0|<非零数字><泛整数><泛整数>→<数字>|<数字><泛整数>|ε<关系符>→<|<=|==|>|>=|<><字母>→A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z<非零数字>→1|2|3|4|5|6|7|8|9<数字>→<非零数字>|0<空>→要求和提示:词法分析阶段,可以打开任意位置和名称的源文件进行词法分析,可以进行非法字符和数字后边跟字母的错误判断,如果没有错误则提示“词法分析正确完成!”,并且可以选择输出token.txt(token文件)string.txt(符号表)两个文件;1.词法分析程序的主要任务如下:①组织源程序的输入,识别出源程序中的各个基本语法单位(也称为单词或语法符号),按规则转换成二元式的形式;②删除无用的空白字符、回车符、及其它非实质性符号;③删除注解行;④为后面的语法和语义分析提供二元式链表;单词编码单词编码标识符1 < 15正整数2 <= 16BEGIN 3 > 17END 4 >= 18IF 5 <> 19THEN 6 == 20ELSE 7 ;21WHILE 8 .22DO 9 := 23INTEGER 10 ,24+ 11 ( 25- 12 )26* 13/ 141) 对标识符的长度控制在8个字符(包括8个)以内,超过的做截断处理;2) 数字不大于65535,否则报错;3) 能跳过源程序中的空白格:两个单词之间的任何空格,制表符,回车,换行都是白空格,除了用来分隔单词以外,没有意义;4) 能跳过注释:a) 接连出现的/*到下一次接连出现的*/之间的任何文字都是注释(多行);b) 从某行接连出现的//到该行的结尾的任何文字都是注释(单行)。
实验一 编译预处理和词法分析
![实验一 编译预处理和词法分析](https://img.taocdn.com/s3/m/84ca81e70975f46527d3e16e.png)
实验一编译预处理和词法分析实验目的:1. 从编译程序的角度理解程序设计语言,并进行编译的预处理。
2. 识别程序设计语言源程序的单词符号。
实验内容:项目1、编写程序,输入为某一C语言源程序(1)输出的结果不对源程序行改变,仅去掉所有注释的内容;(2)把C语言中定义的符号常量能采用对应的常量来替换。
#DEFINE PI 3.14项目2、参考:本教材P32描写TEST语言的单词符号;P218附录B的词法分析程序。
编写程序,输入为某一TEST语言源程序,能分别输出所有标识符、保留字、无符号整数、分界符。
(通过修改附录B的词法分析程序,添加保留字do,双分界符&&和||以及单分界符!的处理)。
实验报告:每位同学撰写一份试验报告,并提交电子版的源程序和报告。
实验报告的要求:项目1:源程序、流程图、运行结果的截图项目2:源程序、流程图、运行结果的截图实验报告命名规则:个人:2013-14(1)医智(1)1107505101蔡菲菲实验一交各班课代表汇总后,由课代表打包后,发送至老师的邮箱班级命名规则:2013-14医智(1)实验一截止日期:第14周周五晚11点30分实验提示:(项目1)以下是一个C++程序,请试着写出它的功能。
#include <fstream.h>#include <iostream.h>void pro_process(char *);void main(){char buf[4048]={'\0'};pro_process(buf);cout<<buf<<endl;}void pro_process(char *buf){ifstream cinf("source.txt",ios::in);int i=0;char old_c='\0',cur_c;bool in_comment=false;while(cinf.read(&cur_c,sizeof(char))) {switch(in_comment){case false:if(old_c=='/'&&cur_c=='*'){i--;in_comment=true;}else{if(old_c=='\\'&& cur_c=='\n') i--;else{if(cur_c>='A'&&cur_c<='Z')cur_c+=32;if(cur_c=='\t'||cur_c=='\n') cur_c=' ';buf[i++] =cur_c;}}break;case true:if(old_c=='*'&&cur_c=='/')in_comment=false;}old_c=cur_c;}buf[i++]='#';}修改后(1)#include<cstdlib>#include<fstream>#include<iostream>using namespace std;void pro_process(char *);void main(){char buf[4048]={'\0'};pro_process(buf);cout<<buf<<endl;{system("pause");}}void pro_process(char *buf){ifstream cinf("source.txt",ios::in);int i=0,j=0,a=0;char old_c='\0',cur_c;bool in_comment=false;while(cinf.read(&cur_c,sizeof(char))){switch(in_comment){case false:if(old_c=='/'&&cur_c=='*'){i--;in_comment=true;}else if(old_c=='P'&&cur_c=='I'){i--;j=1;in_comment=true;}else{if(old_c=='/'&& cur_c=='/'){a=1;i--;in_comment=true;break;}else{buf[i++] =cur_c;}}break;case true:if(old_c=='*'&&cur_c=='/') in_comment=false;if(a){if(cur_c=='\n'){ a=0;in_comment=false;}}if(j){ j=0;buf[i++] ='3';buf[i++] ='.';buf[i++] ='1';buf[i++] ='4';buf[i++] =cur_c;in_comment=false;}}old_c=cur_c;}buf[i++]='#';}流程图:原文本:执行后结果:2. TESTscan:#include <stdio.h>#include <ctype.h>#include <string.h>//下面定义保留,为简化程序,使用字符指针数组保存所有保留字。
【实验报告】实验一-编写词法分析程序
![【实验报告】实验一-编写词法分析程序](https://img.taocdn.com/s3/m/acbb70964b35eefdc9d3331b.png)
编译原理实验报告实验名称:编写词法分析程序_______实验类型:设计型实验指导教师:专业班级:姓名:学号:实验地点:实验成绩:日期:2017年4月15日实验一编写语法分析程序一、实验目的1)通过设计、调试词法分析程序,掌握词法分析程序的设计工具,即有穷自动机,进一步理解自动机理论;2)掌握正则文法和正则表达式转换成有穷自动机的方法及有穷自动机的实现方法;3)会确定词法分析程序的输出形式及标识符与关键字的区分方法;4)加深对课堂教学的理解,提高词法分析方法的实践能力,掌握使用实验环境的技能技巧以及程序的调试方法。
二、实验设计1、写出TEST语言每条词法规则对应的正则文法或者正则表达式1)标识符:字母打头,后接任意字母或数字。
正则表达式:( a|b|……|z|A|B……|Z )( 0|1|……|9| a|b|……|z|A|B……|Z )*2)保留字:标符的子集,包括:if, else, for, while, do, int, write, read。
正则表达式:if | else | for | while | do | int | write | read3)无符号整数:由数字组成,但最高位不能为0,允许一位的0。
正则表达式:( (1……|9 )( 0|1|……|9)* )|04)分界符:(、)、;、{、}正则表达式:( | ) | ; | { | }5)运算符:+、-、*、/、=、<、>、>=、<=、!=、==正则表达式:+ | - | * | / | = | < | > | >= | <= | != | ==6)注释符:/* */正则表达式:/*(没有连续的*/的任意字符串|ℇ)*/2、对每个文法或者正则表达式分别构造NFA1)标识符:( a|b|……|z|A|B……|Z )( 0|1|……|9| a|b|……|z|A|B……|Z )*2)无符号整数:( (1|2|……|9 )( 0|1|……|9)* )|03)分界符:( | ) | ; | { | }4)运算符:+ | - | * | / | = | < | > | >= | <= | != | ==5)注释符:/*(没有连续的*/的任意字符串|ℇ)*/非*非*|非/3、将NFA合并,确定化,化简得到最终的DFA。
(完整word版)编译原理词法分析程序实现实验报告
![(完整word版)编译原理词法分析程序实现实验报告](https://img.taocdn.com/s3/m/1f45afb7b307e87100f69653.png)
(完整word版)编译原理词法分析程序实现实验报告实验一词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。
输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。
输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。
二、设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:GOTO 1:(完整word版)编译原理词法分析程序实现实验报告GOTO 2:三、源程序代码部分#include <stdio.h>#include<stdlib.h>#include <math.h>#define MAX 100#define UNSIGNEDNUMBER 1#define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6#define RIGHTBRACKET 7#define INEFFICACIOUSLABEL 8#define FINISH 111int count=0;int Class;void StoreType();int Type[100];char Store[20]={'\0'};void ShowStrFile();//已经将要识别的字符串存在文件a中void Output(int a,char *p1,char *p2);//字符的输出过程int Sign(char *p);//'+''-''*''/'整体识别过程int UnsignedNum(char *p);//是否适合合法的正整数0~9int LegalCharacter(char *p);//是否是合法的字符:Sign(p)||UnsignedNum(p)||'E'||'.' void DistinguishSign(char *p);//'+''-''*''/'具体识别过程void TypyDistinguish();//字符的识别过程void ShowType();//将类别码存储在Type[100]中,为语法分析做准备void ShowStrFile()//已经将要识别的字符串存在文件a中{FILE *fp_s;char ch;if((fp_s=fopen("a.txt","r"))==NULL){printf("The FILE cannot open!");exit(0);}elsech=fgetc(fp_s);while(ch!=EOF){putchar(ch);ch=fgetc(fp_s);}printf("\n");}void StoreStr()//将文件中的字符串存储到数组Store[i] {FILE *fp=fopen("a.txt","r");char str;int i=0;while(!feof(fp)){fscanf(fp,"%c",&str);if(str=='?'){Store[i]='\0';break;}Store[i]=str;i++;}Store[i]='\0';}void ShowStore(){int i;for (i=0;Store[i]!='\0';i++)printf("%c",Store[i]);printf("\n");}void Output(int a,char *p1,char *p2){printf("%3s\t%d\t%s\t","CLASS",a,"VALUE");while(p1<=p2){printf("%c",*p1);p1++;}printf("\n");}int Sign(char *p){char ch=*p;if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='('||ch==')') return 1;elsereturn 0;}int UnsignedNum(char *p){char ch=*p;if('0'<=ch&&ch<='9')return 1;elsereturn 0;}int LegalCharacter(char *p){char ch=*p;if(Sign(p)||UnsignedNum(p)||ch=='E'||ch=='.')。
实验一 词法分析程序的设计与实现
![实验一 词法分析程序的设计与实现](https://img.taocdn.com/s3/m/46a2031df242336c1eb95efd.png)
实验一词法分析程序的设计与实现一、实验内容【实验目的和要求】设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。
【实验内容】通过对PL/0词法分析程序(GETSYM)的分析,并在此基础上按照附录A中给出的PL/0语言的语法描述,编写一个PL/0语言的词法分析程序。
此程序应具有如下功能:输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。
有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。
【实验环境】Windows PC机,任何语言。
【提交内容】提交实验报告,报告内容如下:目的要求、算法描述、程序结构、主要变量名说明、程序清单、调试情况、设计技巧、心得体会。
提交源程序和可执行文件。
【学时】4课时。
二、实验说明词法分析程序的任务就是扫描源程序,依据词法规则识别单词并报告构词错误信息。
通常将单词分为5种类型。
1)基本字:也叫关键字、保留字,是程序设计语言用来表示特定语法含义的一种标识符,如if、begin等。
2)运算符:如+、-、*、/、:=、>、<等。
3)标识符:用户定义的变量名、常数名、函数名等。
不同的高级程序设计语言对关键字是否可以作为普通标识符有不同的要求,有的语言允许程序员使用关键字作为普通标识符,有的程序设计语言则不允许程序员将关键字用着普通标识符(如C/C++、Pascal等都不允许)。
在允许程序员将关键字用作普通标识符的程序设计语言的编译器中,编译器必须具备能够区分一个标识符到底是关键字还是普通标识符的功能。
4)常数:如23、6等。
5)界符:如“,”、“;”、“(”、“)”、“.”等。
注意事项●空格的作用仅仅是将一个个单词分割开来,源程序中的空格不具备别的语法意义,在语法分析及其后续阶段都没有任何作用,因此,词法分析的另一个工作是过滤空格。
●注释对整个源程序的编译也没有任何语法意义,只是为了便于阅读和交流,因此,有的编译程序的词法分析程序也负责过滤注释。
实验一词法分析程序的设计与实现范文
![实验一词法分析程序的设计与实现范文](https://img.taocdn.com/s3/m/48f48f64b4daa58da1114a26.png)
实验一词法分析程序的设计与实现实验一词法分析程序的设计与实现一、实验内容【实验目的和要求】设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解。
【实验内容】经过对PL/0词法分析程序(GETSYM)的分析,并在此基础上按照附录A中给出的PL/0语言的语法描述,编写一个PL/0语言的词法分析程序。
此程序应具有如下功能:输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。
有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。
【实验环境】Windows PC机,任何语言。
【提交内容】提交实验报告,报告内容如下:目的要求、算法描述、程序结构、主要变量名说明、程序清单、调试情况、设计技巧、心得体会。
提交源程序和可执行文件。
【学时】4课时。
二、实验说明词法分析程序的任务就是扫描源程序,依据词法规则识别单词并报告构词错误信息。
一般将单词分为5种类型。
1)基本字:也叫关键字、保留字,是程序设计语言用来表示特定语法含义的一种标识符,如if、begin等。
2)运算符:如+、-、*、/、:=、>、<等。
3)标识符:用户定义的变量名、常数名、函数名等。
不同的高级程序设计语言对关键字是否能够作为普通标识符有不同的要求,有的语言允许程序员使用关键字作为普通标识符,有的程序设计语言则不允许程序员将关键字用着普通标识符(如C/C++、Pascal等都不允许)。
在允许程序员将关键字用作普通标识符的程序设计语言的编译器中,编译器必须具备能够区分一个标识符到底是关键字还是普通标识符的功能。
4)常数:如23、6等。
5)界符:如“,”、“;”、“(”、“)”、“.”等。
注意事项●空格的作用仅仅是将一个个单词分割开来,源程序中的空格不具备别的语法意义,在语法分析及其后续阶段都没有任何作用,因此,词法分析的另一个工作是过滤空格。
●注释对整个源程序的编译也没有任何语法意义,只是为了便于阅读和交流,因此,有的编译程序的词法分析程序也负责过滤注释。
实验项目一:词法分析程序实验
![实验项目一:词法分析程序实验](https://img.taocdn.com/s3/m/b77f85d6d15abe23492f4d08.png)
实验项目1:词法分析程序实验
实验要求和指导
一、实验的目的与任务:
输入:源程序
输出:单词
二、估计实验时间8学时
1.课余准备;
2.上机一次到二次,第一次编好程序,第二次修改完善,并尽量扩充程序的功能;
3.完成实验报告2小时。
三、实验过程和指导
(一)准备:确定并熟悉开发工具,如C、VC、VC++、Delhi等;充分了解被处理的语言的语法特点(语言定义见下面)。
写好实验报告,编好程序。
(二)上机:安装所需的开发工具,输入或拷贝程序,调试。
四、实验报告要求
1.程序源代码以及可执行文件;
2.已经测试通过的测试数据3组;
3.实验报告按照规定要求书写:
(1)实验步骤
(2)程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;
4.实验总结(提交)。
五、上交文档
1.实验报告
2.程序文件
1。
编译原理实验-词法分析器
![编译原理实验-词法分析器](https://img.taocdn.com/s3/m/4c0cd00bfe00bed5b9f3f90f76c66137ee064fb9.png)
编译原理实验-词法分析器⼀、实验⽬的设计、编制、调试⼀个词法分析程序,对单词进⾏识别和编码,加深对词法分析原理的理解。
⼆、实验内容1.选定语⾔,编辑任意的源程序保存在⽂件中;2.对⽂件中的代码预处理,删除制表符、回车符、换⾏符、注释、多余的空格并将预处理后的代码保存在⽂件中;3.扫描处理后的源程序,分离各个单词符号,显⽰分离的单词类型。
三、实验思路对于实验内容1,选择编写c语⾔的源程序存放在code.txt中,设计⼀个c语⾔的词法分析器,主要包含三部分,⼀部分是预处理函数,第⼆部分是扫描判断单词类型的函数,第三部分是主函数,调⽤其它函数;对于实验内容2,主要实现在预处理函数processor()中,使⽤⽂档操作函数打开源程序⽂件(code.txt),去除两种类型(“//”,“/*…*/”)的注释、多余的空格合并为⼀个、换⾏符、回车符等,然后将处理后的保存在另⼀个新的⽂件(afterdel.txt)中,最后关闭⽂档。
对于实验内容3,打开处理后的⽂件,然后调⽤扫描函数,从⽂件⾥读取⼀个单词调⽤判断单词类型的函数与之前建⽴的符号表进⾏对⽐判断,最后格式化输出。
四、编码设计代码参考了两篇博主的,做了部分改动,添加了预处理函数等1 #include<iostream>2 #include<fstream>3 #include<cstdio>4 #include<cstring>5 #include<string>6 #include<cstdlib>78using namespace std;910int aa;// fseek的时候⽤来接着的11string word="";12string reserved_word[20];//保留13char buffer;//每次读进来的⼀个字符14int num=0;//每个单词中当前字符的位置15int line=1; //⾏数16int row=1; //列数,就是每⾏的第⼏个17bool flag; //⽂件是否结束了18int flag2;//单词的类型192021//预处理函数22int processor(){//预处理函数23 FILE *p;24int falg = 0,len,i=0,j=0;25char str[1000],str1[1000],c;26if((p=fopen("code.txt","rt"))==NULL){27 printf("⽆法打开要编译的源程序");28return0;29 }30else{31//fgets(str,1000,p);32while((c=getc(p))!=EOF){33 str[i++] = c;34 }35 fclose(p);36 str[i] = '\0';37for(i=0;i<strlen(str);i++){38if(str[i]=='/'&&str[i+1]=='/'){39while(str[i++]!='\n'){}40 }//单⾏注释41else if(str[i]=='/'&&str[i+1]=='*'){42while(!(str[i]=='*'&&str[i+1]=='/')){i++;}43 i+=2;44 }//多⾏注释45else if(str[i]==''&&str[i+1]==''){46while(str[i]==''){i++;}47 i--;48if(str1[j-1]!='')49 str1[j++]='';50 }//多个空格,去除空格51else if(str[i]=='\n') {52if(str1[j-1]!='')53 str1[j++]='';54 }//换⾏处理,55else if(str[i]==9){56while(str[i]==9){57 i++;58 }59if(str1[j-1]!='')60 str1[j++]='';61 i--;62 }//tab键处理63else str1[j++] = str[i];//其他字符处理64 }65 str1[j] = '\0';66if((p = fopen("afterdel.txt","w"))==NULL){ 67 printf("can not find it!");68return0;69 }70else{71if(fputs(str1,p)!=0){72 printf("预处理失败!");73 }74else printf("预处理成功!");75 }76 fclose(p);77 }78return0;79 }8081//设置保留字82void set_reserve()83 {84 reserved_word[1]="return";85 reserved_word[2]="def";86 reserved_word[3]="if";87 reserved_word[4]="else";88 reserved_word[5]="while";89 reserved_word[6]="return";90 reserved_word[7]="char";91 reserved_word[8]="for";92 reserved_word[9]="and";93 reserved_word[10]="or";94 reserved_word[11]="int";95 reserved_word[12]="bool";96 }9798//看这个字是不是字母99bool judge_word(char x)100 {101if(x>='a' && x<='z' || x>='A' && x<='Z' ){ 102return true;103 }104else return false;105 }106107//看这个字是不是数字108bool judge_number(char x)109 {110if(x>='0' && x<='9'){111return true;112 }113else return false;114 }115116//看这个字符是不是界符117bool judge_jiefu(char x)118 {119if(x=='('||x==')'||x==','||x==';'||x=='{'||x=='}'){ 120return true;121 }122else return false;123 }124125126//加减乘127bool judge_yunsuanfu1(char x)128 {129if(x=='+'||x=='-'||x=='*')130 {131return true;132 }133else return false;134 }135136//等于赋值,⼤于⼩于⼤于等于,⼩于等于,⼤于⼩于137bool judge_yunsuannfu2(char x)138 {139if(x=='='|| x=='>'||x=='<'||x=='&'||x=='||'){140return true;141 }142else return false;143 }144145146//这个最⼤的函数的总体作⽤是从⽂件⾥读⼀个单词147int scan(FILE *fp)148 {149 buffer=fgetc(fp);//读取⼀个字符150if(feof(fp)){//检测结束符151 flag=0;return0;152 }153else if(buffer=='')154 {155 row++;156return0;157 }158else if(buffer=='\n')159 {160 row=1;161return0;162 }163//如果是字母开头或'_' 看关键字还是普通单词164else if(judge_word(buffer) || buffer=='_')165 {166 word+=buffer;167 row++;168while((buffer=fgetc(fp)) && (judge_word(buffer) || judge_number(buffer) || buffer=='_'))169 {170 word+=buffer;171 row++;172 }173if(feof(fp)){174 flag=0;175return1;176 }177for(int i=1;i<=12;i++){178if(word==reserved_word[i]){179 aa=fseek(fp,-1,SEEK_CUR);//如果执⾏成功,stream将指向以fromwhere为基准,偏移offset(指针偏移量)个字节的位置,函数返回0。
编译原理实验报告2-词法分析程序的设计.
![编译原理实验报告2-词法分析程序的设计.](https://img.taocdn.com/s3/m/77972c26bed5b9f3f90f1cb6.png)
实验2 词法分析程序的设计一、实验目的掌握计算机语言的词法分析程序的开发方法。
二、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求1、根据以下的正规式,编制正规文法,画出状态图;标识符<字母>(<字母>|<数字字符>)*十进制整数0 | ((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*运算符和界符+ - * / > < = ( ) ;关键字if then else while do2、根据状态图,设计词法分析函数int scan( ),完成以下功能:1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,2)以二元式形式输出单词<单词种类,单词属性>其中单词种类用整数表示:0:标识符1:十进制整数2:八进制整数3:十六进制整数运算符和界符,关键字采用一字一符,不编码其中单词属性表示如下:标识符,整数由于采用一类一符,属性用单词表示运算符和界符,关键字采用一字一符,属性为空3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。
四、实验环境PC微机DOS操作系统或Windows 操作系统Turbo C 程序集成环境或Visual C++ 程序集成环境五、实验步骤1、根据正规式,画出状态转换图;2、根据状态图,设计词法分析算法;观察状态图,其中状态2、4、7、10(右上角打了星号)需要回调一个字符。
声明一些变量和函数:ch: 字符变量,存放最新读进的源程序字符。
strToken: 字符串变量,存放构成单词符号的字符串。
编译原理实验(词法分析程序设计)
![编译原理实验(词法分析程序设计)](https://img.taocdn.com/s3/m/27a040fef8c75fbfc77db2c9.png)
int Iskey(string c){ //关键字判断
int i;
for(i=0;i<MAX;i++) {
if(key[i].compare(c)==0) return 1;
}
return 0;
if((ch<='Z')&&(ch>='A')) ch=ch+32;
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
if (Iskey(arr)){cout<<arr<<"\t$关键字"<<endl;}
else cout<<arr<<"\t$普通标识符"<<endl;
analyse(fpin);
fclose(fpin);
}
实验记录
程序测试:
1、文件位置:f:\\11.txt
目标程序如下:
begin
x:=9
if x>0 then x:=x+1;
while a:=0 do
b:=2*x/3;
end;
2、运行结果:
实验总结
通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言(例如C++语言)直接编写此法分析程序。另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。以后我会更加专心的研究计算机知识,不断将现实中遇到的实际问题,向程序方面转变,做到灵活运用所学知识。
编译原理-实验一.词法分析程序
![编译原理-实验一.词法分析程序](https://img.taocdn.com/s3/m/fc80c9c42cc58bd63186bdee.png)
实验一.词法分析程序一.实验目的:1>通过设计和实现一个词法分析程序,加深对词法分析原理的理解;2>掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法;二.实验内容:1>编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)词法分析器的功能是输入源程序,输出单词符号。
词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。
2>保留字:if、then、else、while、do;单词种别码为1;标识符;单词种别码为2;无符号整形数;单词种别码为3;运算符包括:+、-、*、/、=、<、>、<=、>=;单词种别码为4;分隔符包括:;、(、);单词种别码为5;if (a>10) then b = a + 20;(1,”if”)(5,”(”)(2,”a”)(4,”>”)(3,”10”)(5,”)”)(1,”then ”)(2,”b”)(4,”=”)(2,”a”)(4,”+”)(3,”20”)(5,”; ”)三.运行结果及代码:#include<stdio.h>#include<string.h>#include<iostream.h>char prog[80],token[8];char ch;int syn,p,q,m=0,n,sum=0;char *rwtab[5]={"else","if","then","while","do"};//种别码1char *operat[9]={"+","-","*","/",">","<",">=","<=","="};// 4int scaner(){for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];//while(ch=='_')//ch=prog[p++];if((ch>='A'&&ch<='Z')||( ch>='a'&&ch<='z')){ m=0;while((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')/*||(ch>='0'&&ch<='9')*/){token[m++]=ch;//token[m++]=ch;ch=prog[p++];for(n=0;n<5;n++)if(strcmp(token,rwtab[n])==0)//111111111111111111111{syn=1;//syn=n+1;token[m++]='\0';p--;return 0;}}token[m++]='\0';p--;syn=2;//syn=10;//22222222222222222222222222222222222222222return 0;}if((ch=='+')||(ch=='-')||(ch=='*')||(ch=='/')||(ch=='=')||(ch=='>=')||(ch=='<=')||ch=='<'||ch=='>') {syn=4;token[0]=ch;token[1]='\0';return 0;}else if(ch>='0'&&ch<='9'){ sum=0;while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=3;//syn=11;}/*elseif(ch=='*')syn=13;else if(ch=='/')syn=14;else if(ch=='+')syn=15;else if(ch=='-')syn=16;else if(ch=='>'){ch=prog[p++];if(ch=='=') syn=24;else syn=20;}else if(ch==':'){ch=prog[p++];if(ch=='=') syn=18;else syn=17;}else if(ch=='<'){ch=prog[p++];if(ch=='=') syn=22;else if(ch=='>') syn=21;else syn=23;}else if(ch=='=')syn=25;*/else if(ch==';' ||ch=='('||ch==')')syn=5;else if(ch=='#')syn=0;return 0;}int main(){p=0;cout<<"词法分析\n 请输入源程序: \n";do {cin>>ch;prog[p++]=ch;}while(ch!='#');q=p;p=0;do{scaner();switch(syn){ case 3: cout<<"(3,"<<sum<<")\n";break;case -1: cout<<"error!"; break;case 4: cout<<"(4,"<<ch<<")"<<endl;break;case 5:cout<<"(5,"<<ch<<")\n";break;case 0:cout<<"(0,#)"<<endl;break;default: cout<<"("<<syn<<","<<token<<")\n";}}while (syn!=0);return 0;}四.心得与体会:通过本次实验,对词法分析原理有了更深层次的理解,掌握了程序设计语言源程序进行扫描过程中为其分解为各类单词的词法分析方法,提高了动手能力,虽然在实验过程中遇到了一些问题,经过同学的帮助,得以解决。
实验一 词法分析程序的设计与实现
![实验一 词法分析程序的设计与实现](https://img.taocdn.com/s3/m/5890410d02020740be1e9bbb.png)
实验项目一词法分析程序的设计与实现实验目的1. 学会针对DFA转换图实现相应的高级语言源程序。
2. 深刻领会状态转换图的含义,逐步理解有限自动机。
3. 掌握手工生成词法分析器的方法,了解词法分析器的内部工作原理。
实验内容计算机语言的编译程序的词法分析部分实现。
从左到右扫描每行该语言源程序的符号,拼成单词,换成统一的内部表示(token)送给语法分析程序。
为了简化程序的编写,有具体的要求如下:1)整数或浮点数。
2)空白符仅仅是空格、回车符\n、制表符\t。
3)代码是自由格式。
4)注释应放在花括号或者/* */或者// 之内,并且不允许嵌套要求实现编译器的以下功能:1)按规则拼单词,并转换成二元式形式2)删除注释行3)删除空白符(空格、回车符、制表符),即中间表示形式中不含空白符。
4)列表打印源程序,按照源程序的行打印,在每行的前面加上行号,并且打印出每行包含的记号的二元形式5)能发现并定位词法错误词法分析建议:1)记号的二元式形式中种类采用枚举方法定义;其中保留字和特殊字符是每个都一个种类,标示符自己是一类,数字是一类;单词的属性值就是表示的字符串值。
2)词法分析的具体功能实现是一个函数GetToken(),每次调用都对剩余的字符串分析得到一个单词或记号识别其种类,收集该记号的符号串属性,当识别一个单词完毕,采用返回值的形式返回符号的种类,同时采用程序变量的形式提供当前识别出记号的属性值。
3)标示符和保留字的词法构成相同,为了更好的实现,把语言的保留字建立一个表格存储,这样可以把保留字的识别放在标示符之后,用识别出的标示符对比该表格,如果在该表格中则是保留字,否则是一般标示符。
词法分析的过程可如下描述:测试测试该设计词法分析器,代码可自选,例如自己编写的某段程序。
输入与输出形式:例如输入main() {int i = 10;while(i) i = i - 1;}输出如下二元式代码序列:1, (1,main) (26,() (27,)) (30,{)2, (2,int) (10,i) (21,=) (20,10) (34,;)3, (7,while) (26,() (10,i) (27,)) (10,i) (21, =) (10,i) (23,-) (20,1) (34,;) 4, (31,})测试代码:/*PROGRAM 求max*/float max2(float x, float y){ float max;if(x>y) max=x;else max=y;return max;}main( ){ float a,b,max;printf("Input values of a and b: "); scanf("%f%f",&a,&b);max=max2(a,b);printf("max(%f,%f)=%f\n",a,b, max); }。
实验一源程序的预处理及词法分析程序设计
![实验一源程序的预处理及词法分析程序设计](https://img.taocdn.com/s3/m/aac8c6280812a21614791711cc7931b765ce7b93.png)
实验一源程序的预处理及词法分析程序设计(6学时)一、实验目的设计并实现一个包含预处理功能的词法分析程序,加深对编译中词法分析过程的理解。
二、实验要求1、实现预处理功能源程序中可能包含有对程序执行无意义的符号,要求将其剔除。
首先编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);然后编制一个预处理子程序,去掉输入串中的回车符、换行符和跳格符等编辑性文字;把多个空白符合并为一个;去掉注释。
2、实现词法分析功能输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中,syn为单词种别码。
Token为存放的单词自身字符串。
Sum为整型常量。
具体实现时,可以将单词的二元组用结构进行处理。
3、待分析的C语言子集的词法1)关键字main if then while do static int double struct break else long switch case typedef char return const float shortcontinue for void default sizeof do所有的关键字都是小写。
2)运算符和界符+ - * / : := < <> <= > >= = ; ( ) #3)其他标记ID和NUM通过以下正规式定义其他标记:ID→letter(letter|digit)*NUM→digit digit*letter→a|…|z|A|…|Zdigit→0|…|9…4)空格由空白、制表符和换行符组成空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。
4、各种单词符号对应的种别码表1 各种单词符号的种别码单词符号种别码单词符号种别码main 1 ; 41if 2 ( 42then 3 ) 43while 4 int 7do 5 double 8static 6 struct 9ID 25 break 10NUM 26 else 11+ 27 long 12- 28 switch 13* 29 case 14/ 30 typedef 15: 31 char 16:= 32 return 17< 33 const 18<> 34 float 19<= 35 short 20> 36 continue 21>= 37 for 22= 38 void 23default 39 sizeof 24do 40 # 05、词法分析程序的主要算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到的单词符号的第一个字符的种类,拼出相应的单词符号。
源程序的预处理及词法分析程序设计
![源程序的预处理及词法分析程序设计](https://img.taocdn.com/s3/m/6e76a65c312b3169a451a4a1.png)
//词法分析#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>using namespace std;void chu_li_1(FILE *p,FILE *q) //处理空格{charch;if((p=fopen("输出文件.txt","r+"))==NULL) //shili3.txt为中转文件{cout<<"输出文件打开错误"<<endl;}if((q=fopen("中转文件.txt","w+"))==NULL) //保存处理后程序的文件{cout<<"中转文件打开错误"<<endl;}while(!feof(p)){ch=fgetc(p);if(ch!=32)fputc(ch,q); //保留一个空格else if(ch==32) //将多个空格删除{fputc(ch,q);while(1&&(ch!=EOF)){ch=fgetc(p);if(ch!=32) //空格结束{fputc(ch,q);break;}}}}fclose(p);fclose(q);}void chu_li_2(FILE *p,FILE *q) //处理换行{charch;if((p=fopen("中转文件.txt","r+"))==NULL){cout<<"中转文件打开错误"<<endl;}if((q=fopen("输出文件.txt","w+"))==NULL){cout<<"输出文件打开错误"<<endl;}while((ch=fgetc(p))!=EOF){if(ch!='\n') //忽略换行符fputc(ch,q);}fclose(p);fclose(q);}void chu_li_3(FILE *p,FILE *q) //处理注释{charch;if((p=fopen("输入文件.txt","r+"))==NULL) //程序输入文件{if((p=fopen("输入文件.txt","w+"))==NULL) //程序输入文件{cout<<"输入文件打开错误"<<endl;}}if((q=fopen("中转文件.txt","w+"))==NULL){cout<<"中转文件打开错误"<<endl;}while((ch=fgetc(p))!=EOF){if(ch==47) //程序中发现字符'/'{ch=fgetc(p);if(ch==42) //判断字符后'/'是否有字符'*'{while(1){ch=fgetc(p); //忽略注释内容if(ch==42) //直到有'*'出现{ch=fgetc(p);if(ch==47) //判断结束break;}}}else if(ch==47) //判断以"//"开头形式的注释{while((ch!='\n')&&((ch=fgetc(p))!=EOF))ch=fgetc(p);}else{fputc('/',q); //将不属于注释标示符的字符'/'写入文件fputc(ch,q); //}}elsefputc(ch,q);}fclose(p);fclose(q);}void Y_C_L(FILE *p,FILE *q) //预处理函数{chu_li_3(p,q); //处理注释chu_li_2(p,q); // 处理换行chu_li_1(p,q); //处理空格}voidFen_xi(){FILE *p,*q;charch;intm,n=0;char letter[20000]="\0";char *rwtab[44]={"#","main","if","then","while","do","static", "int"," double","struct","break","else","long","switch","case","typedef","char","return","const","float","short","continue","for","void","sizeof","ID","NUM","+","-","*","/",":",":=","<","<>","<=",">",">=","=","default","include",";","(",")"};if((p=fopen("中转文件.txt","r+"))==NULL)cout<<"中转文件打开错误"<<endl;if((q=fopen("输出文件.txt","w+"))==NULL)cout<<"输出文件打开错误"<<endl;fputs("Token",q);fputs("\t\t",q);fputs("Syn",q);fputc('\n',q);ch=fgetc(p);while(ch!=EOF){ m=1;letter[0]=ch;if(letter[0]<=57&&letter[0]>=48)//开头是数字{while(1&&ch!=EOF)//直到不是数字时为止{ch=fgetc(p);if(ch>=48&&ch<=57)letter[m++]=ch;elsebreak;}cout<<letter<<'\t'<<'\t'<<"26"<<endl;//输出读入的数字fputs(letter,q);fputs("\t\t",q);fputs("26",q);fputc('\n',q);for(int j=0;j<20000;j++)//将缓存数组清零letter[j]='\0';letter[0]=ch;}else if((letter[0]<='z'&&letter[0]>='a')||(letter[0]<='Z'&&letter[0]>='A'))//开头是字母{ int H=0;while(1&&!ch!=EOF)//直到不是字母或数字时为止{ch=fgetc(p);if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'))letter[m++]=ch;elsebreak;}for(n=0;n<44;n++)//对初始表进行比较查看是否是关键字{if(strcmp(letter,rwtab[n])==0){cout<<letter<<'\t'<<'\t'<<n<<endl;fputs(letter,q);fputs("\t\t",q);fprintf(q,"%d",n);fputc('\n',q);H=1;}}if(H==0)//如果比较完时没有,该字符量就是一般字符串{cout<<letter<<'\t'<<"25"<<endl;fputs(letter,q);fputs("\t\t",q);fputs("25",q);fputc('\n',q);}for(int j=0;j<20000;j++)//将缓存数组清零letter[j]='\0';letter[0]=ch;}else if((letter[0]>=' '&&letter[0]<='/')||(letter[0]>=':'&&letter[0]<='?')){ int H=0;if(letter[0]==' '||letter[0]=='!'||letter[0]=='\"'||letter[0]=='$'||letter[0]=='%' ||letter[0]=='&'||letter[0]=='\''||letter[0]==','||letter[0]=='.'||letter[0]=='?') ch=fgetc(p);else{while(ch!=EOF){ch=fgetc(p);if(((ch>' '&&ch<='/')||(ch>=':'&&ch<'?'))&&(ch!=' '||ch!='!'||ch!='\"'||ch!='$'||ch!='%'||ch!='&'||ch!='\''||ch!=','||ch!='.'||ch!='?'))letter[m++]=ch;elsebreak;}for(n=0;n<44;n++)//对初始表进行比较查看是否是关键字{if(strcmp(letter,rwtab[n])==0){cout<<letter<<'\t'<<n<<endl;fputs(letter,q);fputs("\t\t",q);fprintf(q,"%d",n);fputc('\n',q);H=1;}}if(H==0)//如果比较完时没有,该字符量就是一般字符串{cout<<"sorry!字符"<<letter<<"不存在!"<<endl; fputs("sorry!字符",q);fputs(letter,q);fputs("不存在!",q);fputc('\n',q);}for(int j=0;j<20000;j++)//将缓存数组清零letter[j]='\0';letter[0]=ch;}}else{cout<<"sorry!字符"<<ch<<"非系统能识别的字符!"<<endl; fputs("sorry!字符",q);fputc(ch,q);fputs("非系统能识别的字符!",q);fputc('\n',q);ch=fgetc(p);}}fclose(p);fclose(q);}int main(){FILE *fp1,*fp2;Y_C_L(fp1,fp2); //预处理函数cout<<"Token"<<"\t\t"<<"Syn"<<endl;Fen_xi();//分析分类并输出system("pause");}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一源程序的预处理及词法分析程序设计
(6学时)
一、实验目的
设计并实现一个包含预处理功能的词法分析程序,加深对编译中词法分析过程的理解。
二、实验要求
1、实现预处理功能
源程序中可能包含有对程序执行无意义的符号,要求将其剔除。
首先编制一个源程序的输入过程,从键盘、文件或文本框输入若干行语句,依次存入输入缓冲区(字符型数据);然后编制一个预处理子程序,去掉输入串中的回车符、换行符和跳格符等编辑性文字;把多个空白符合并为一个;去掉注释。
2、实现词法分析功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中,
syn为单词种别码。
Token为存放的单词自身字符串。
Sum为整型常量。
具体实现时,可以将单词的二元组用结构进行处理。
3、待分析的C语言子集的词法
1)关键字
main if then while do static int double struct break else long switch case typedef char return const float short
continue for void default sizeof do
所有的关键字都是小写。
2)运算符和界符
+ - * / : := < <> <= > >= = ; ( ) #
3)其他标记ID和NUM
通过以下正规式定义其他标记:
ID→letter(letter|digit)*
NUM→digit digit*
letter→a|…|z|A|…|Z
digit→0|…|9…
4)空格由空白、制表符和换行符组成
空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。
4、各种单词符号对应的种别码
表1 各种单词符号的种别码
单词符号种别码单词符号种别码
main 1 ; 41
if 2 ( 42
then 3 ) 43
while 4 int 7
do 5 double 8
static 6 struct 9
ID 25 break 10
NUM 26 else 11
+ 27 long 12
- 28 switch 13
* 29 case 14
/ 30 typedef 15
: 31 char 16
:= 32 return 17
< 33 const 18
<> 34 float 19
<= 35 short 20
> 36 continue 21
>= 37 for 22
= 38 void 23
default 39 sizeof 24
do 40 # 0
5、词法分析程序的主要算法思想
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到的单词符号的第一个字符的种类,拼出相应的单词符号。
1. 主程序示意图
主程序示意图如图1所示。
图1 词法分析主程序示意图
其中初值包括如下两方面:
(1)关键字表初值
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则
为一般标识符。
关键字表为一个字符串数组,其描述如下:
char *rwtab[27]={“main”,”if”,”then”,”while”,”do”,”
static”,”int”,”
double”,”struct”,”break”,”else”,”long”,”switch”,”case”,”typedef”,”c
har”,”return”,”const”,”float”,”short”,”continue”,”for”,”void”,”defa
ult”,”sizeof”,”do”};
(2) 程序中需要用到的主要变量:syn,token和sum。
2. 扫描子程序的算法思想
首先设置三个变量:token用来存放构成单词符号的字符串;sum用来存放整型单
图2 词法分析程序流程
三、实验报告要求
1.写出编程思路、源代码(或流程图);
2.写出上机调试时发现的问题,以及解决的过程;
3.写出你所使用的测试数据及结果;
4.谈谈你的体会。
5.上机6小时,完成实验报告2小时。