编译原理 实验1《词法分析程序设计与实现》
实验1《词法分析程序设计与实现》
一、实验目的
加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对简单的程序段进行词法分析。
二、实验内容
自定义一种程序设计语言,或者选择已有的一种高级语言,编制它的词法分析程序。词法分析程序的实现可以采用任何一种编程语言和编程工具。
从输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、常数、运算符、界符。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)
三、实验方法
- 实验采用C++程序语言进行设计,利用txt文本对源程序进行存储;
- 实验先自定义词法规则,更具定义的词法规则绘制对应的DFA图,根据DFA图进行源程序编写;
- 源程序编写先定义部分函数,比如判断字符串是否为关键字、是否为运算符等,再进行源程序编写;
四、实验步骤
定义目标语言的可用符号表;
1.1 关键字:int、char、string、bool、float、double、true、false、return、if、else、while、for、default、do、public、static、switch。关键字的内部编码为1;
1.2 标识符:①标识符由字母、数字、下划线(_)组成;②不能把C++关键字作为标识符;③标识符对大小写敏感;④首字符只能是字母或下划线,不能是数字。标识符的内部编码为2。
1.3 常数:无符号整数值。常量的内部编码为3。
1.4 运算符:+、-、*、/、^、=、<=、>=、!=。运算符的内部编码为4。
1.5 界符:,、;、{、}、(、)。界符的内部编码为5。定义程序输入输出;
2.1 程序输入:依照C++程序规则输入,以txt文本形式存储;
2.2 程序输出:程序依照<单词内部编码,值>的形式每行一个进行输出,例如(5,”(”)。依据读入的规则,构造本词法分析器的DFA图;
根据程序要求,绘制流程图;
编写源程序,依次读入源程序符号,对源程序进行逐个字符的读入,然后判别再处理,直到源程序结束;
对正确的单词,按照<单词内部编码,值>的形式进行输出;
对不正确的单词,做出错误处理,并进行记录输出。
五、实验结果
- 实验的测试源代码为:
实验测试源代码中包含关键字(int、if)、标识符(main、_a2、b)、常数(10、20、3-5)、运算符(=、+、<=)、分隔符(;、(、)、{、})以及错误输入(==、%、3ab),对应自定义的目标可用符号表内容均包含在内,能够完整的展示程序功能。
test1.txt:
main(){int _a2,b;_a2 == 10;b = a + 20;
%int 3ab;if(a<=3){a=5;}
}
- 实验测试结果:
测试结果符合预期结果,根据自定义的词法结构,程序对源程序进行识别的单词类别与值均能一一对应,一些错误输入或者未定义的字符也能以Error形式进行标识,比如(Error,”%”)。实验截图如下所示:
六、实验结论
- 实验利用自定义的源程序进行测试,结果正确,符合预期结果,测试源码及结果截图和说明如上所示。
- 实验源代码如下所示:
test1.cpp
/**************************
Compiler Principle
test1 lexical analyzer
author:zz
codeblocks
2019.03.29
***************************/#include <iostream>
#include <fstream>
#include <cassert>
#include <string>using namespace std;//判断当前字符串是否为关键字
bool isKey(string s){//关键字数组string keyArray[] = {"int","char","string","bool","float","double","float","true","false","return","if","else","while","for","default","do","public","static","switch"};//与当前字符串一一对比for(int i=0;i<sizeof(keyArray);i++){if(keyArray[i] == s){return true;}else{return false;}}
}//判断当前字符是否是运算符
bool isOperator(char ch){if('+'==ch || '-'==ch || '*'==ch || '/'==ch || '^'==ch || '='==ch || '<'==ch || '>'==ch || '!'==ch)return true;elsereturn false;
}//判断当前字符是否是分隔符
bool isSeparator(char ch){if(','==ch || ';'==ch || '{'==ch || '}'==ch || '('==ch || ')'==ch)return true;elsereturn false;
}int main( )
{//定义字符变量,保存从源程序中读取的单个字符char ch;//定义字符串,保存从源程序中连续读取的字符串string result;//存放每个获取的单词的值string resultArray[999];//记录获取单词的个数int resultNum=0;//代码存放的文件名string file = "test1.txt";ifstream infile;//将文件流对象与文件连接起来infile.open(file.data());//若失败,则输出错误消息,并终止程序运行assert(infile.is_open());//txt文本中读取空格符与换行符//infile >> noskipws;//读取文本中的一个字符infile>>ch;while (!infile.eof()){//ch是英文字母或者下划线if(isalpha(ch) || '_'==ch){result.append(1,ch);infile>>ch;//判断是否为关键字if(isKey(result)){resultArray[resultNum++]="(1,\""+result+"\")";result="";}//读入首字符为字母,继续读入字母、数字、下划线,组成标识符或者关键字while(isalpha(ch) || isdigit(ch) || '_'==ch){result.append(1,ch);infile>>ch;if(isKey(result)){resultArray[resultNum++]="(1,\""+result+"\")";result="";}}//读入操作符或者运算符,正确保存标识符或者关键字if(isSeparator(ch) || isOperator(ch)){if(isKey(result)){resultArray[resultNum++]="(1,\""+result+"\")";result="";continue;}else{if(isdigit(result.at(0))){resultArray[resultNum++]="(Error,\""+result+"\")";}else{resultArray[resultNum++]="(2,\""+result+"\")";}result="";continue;}}//读入不是字母、数字、运算符、标识符,继续读入直到遇到运算符或者分隔符else{result.append(1,ch);infile>>ch;while(!isSeparator(ch) && !isOperator(ch)){result.append(1,ch);infile>>ch;}resultArray[resultNum++]="(Error,\""+result+"\")";result="";continue;}}//读入数字else if(isdigit(ch)){result.append(1,ch);infile>>ch;//继续读入数字,组成常数while(isdigit(ch)){result.append(1,ch);infile>>ch;}//遇到操作符或者运算符,正常终止if(isOperator(ch) || isSeparator(ch)){resultArray[resultNum++]="(3,\""+result+"\")";result="";continue;}//读入其他错误字符else{result.append(1,ch);infile>>ch;while(!isSeparator(ch) && !isOperator(ch)){result.append(1,ch);infile>>ch;}resultArray[resultNum++]="(Error,\""+result+"\")";result="";continue;}}//遇到运算符else if(isOperator(ch)){result.append(1,ch);infile>>ch;//判断是否存在<=、>=、!=if("<"==result || ">"==result || "!"==result){if('='==ch){result.append(1,ch);infile>>ch;}}//下一个读入符为字母、数字、分隔符,即正确if(isalpha(ch) || isdigit(ch) || isSeparator(ch)){resultArray[resultNum++]="(4,\""+result+"\")";result="";continue;}else{//将错误输入符一起读入,直到正确while(!isSeparator(ch) && !isalpha(ch) && !isdigit(ch)){result.append(1,ch);infile>>ch;}resultArray[resultNum++]="(Error,\""+result+"\")";result="";continue;}}//读取到分隔符else if(isSeparator(ch)){result.append(1,ch);resultArray[resultNum++]="(5,\""+result+"\")";result="";infile>>ch;}//读取到未定义输入else{//出错处理result.append(1,ch);resultArray[resultNum++]="(Error,\""+result+"\")";result="";infile>>ch;}}//关闭文件输入流infile.close();//以 (单词类编码,值) 输出结果for(int i=0;i<resultNum;i++){cout<<resultArray[i]<<endl;}return 0;
}
七、实验小结
- 本次实验最主要的是通过对源代码进行分析得到一个个的单词,通过编程实现后对词法分析这一过程更加的熟悉了。
- 实验过程中第一个问题是如何利用C++进行txt文档读取,并逐个获取到单个字符。
解决方式:通过谷歌搜索,得知C++的读取txt文本的方式,同时通过设计可以只读取字符,直接忽略空格与换行符。 - 实验过程读取关键字后读取下划线开头的标识符与以数字开头的标识符不能正确区分。
解决方式:在读取关键字后,加入continue重新进行字符读取,直接进入下一次循环即可正确识别。 - 对于实验部分控制输出的代码重复率比较高,可以进一步优化,但是如果写成函数则读取字符不方便操作,所以暂未改进。
编译原理 实验1《词法分析程序设计与实现》相关推荐
- 编译原理实验一 词法分析程序设计与实现
一.实验目的 通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符流形式的源程序转化为一个由各类单词构成的序列的词法分析方法. 二.基本实验内容与要求 假定一种高级程序 ...
- 编译原理 实验二 词法分析程序设计
1. 实验内容 ● TINY语言的词法由TINY Syntax.ppt描述: ● TINY语言的词法分析器由TINY Scanner.rar的C语言代码实现: ● TINY+语言的词法由TINY+ S ...
- 编译原理实验:词法分析
编译原理实验:词法分析 1. 实验题目:词法分析 实验目的 实验内容 实验要求 输入输出 2. 设计思想 3.算法流程 4. 源程序 5. 调试数据 1. 实验题目:词法分析 实验目的 根据PL/0语 ...
- 编译原理实验三 语义分析程序设计与实现
一.实验目的 在实现词法.语法分析程序的基础上,编写相应的语义子程序,进行语义处理,加深对语法制导翻译原理的理解,进一步掌握将语法分析所识别的语法范畴变换为某种中间代码(四元式)的语义分析方法,并完成 ...
- 编译原理实验代码c语言,编译原理实验 简单词法分析(含源代码和实验结果)
可直接运行 原创!! 附录一 实验报告样式 <编译原理>实验报告 实验2 简单词法分析 姓名 陈婷婷 学号 1009050121 班级 计科1001班 时间: 2012/4/5 地点:文波 ...
- 编译原理实验一、 程序设计语言认知实验报告
一.实验目的 了解程序设计语言的发展历史,了解不同程序设计语言的各自特点:感受编译执行和解释执行两种不同的执行方式,初步体验语言对编译器设计的影响,为后续编译程序的设计和开发奠定良好的基础. 二.实验 ...
- 编译原理实验c语言cfg文法,编译原理
地址在符号表中引入指针previous,来连接上一个符号的首地址运行时存储空间组织活动记录用于管理函数变量的信息栈式存储过程进入和返回通过变更top和sp指针,实现活动记录的栈式处理静态链实现局部变量 ...
- 编译原理实验二:赋值语句的语法分析程序设计
编译原理实验二:赋值语句的语法分析程序设计 1.1实验内容 目的: 在前面实验的基础上,通过设计.编制.调试一个典型的赋值语句的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查,进一步掌握 ...
- 词法分析程序的设计(编译原理实验一)
词法分析程序的设计(编译原理实验一) 一.实验内容 编制一个能够分析三种整数.标识符.主要运算符和主要关键字的词法分析程序. 二.实验要求 编写程序,识别如下单词符号 标识符 <字母> ...
- html解析器编译原理,编译原理实验报告词法分析器(内含源代码).docx
编译原理实验报告词法分析器(内含源代码) 编译原理实验(一) --词法分析器 实验描述 运行环境:vc++2008 对某特定语言A ,构造其词法规则. 该语言的单词符号包括: 1该程序能识别的单词符号 ...
最新文章
- java.lang.NullPointerException异常原因及解决
- python代码块使用缩进表示-Python 为什么抛弃累赘的花括号,使用缩进来划分代码块?...
- as工程放到源码编译_关于AS高版本SDK编译生成的apk放入低版本android源码中集成编译...
- Python 爬虫浏览器伪装技术
- 汉诺塔-递归算法深入理解
- python 内置递归
- 华为云客户端_华为公布云手机计费清单,要不要光刻机也给出了答案
- 实锤!Python 真没你想的那么简单…
- 利用建站快速软件包:XAMPP,构建基于winodws平台快速搭建PHP的数据库应用- kimai - 团队时间记录
- 如何解决gcc版本冲突?
- C++primer 7.4节练习
- 白光led 计算机模拟,大动态白光LED光辐射模拟器
- 《动手学深度学习》(PyTorch版)代码注释 - 50 【Semantic_segmentation】
- 用php语言说句情话,说给女朋友的感动情话50句
- java 基础运算_Java 基础 运算符
- 【并发编程】map 基本用法和常见错误以及如何实现线程安全的map类型
- 3D-GIS地理信息系统研发解决方案
- 计算机应用技能大赛总结,大学生计算机应用技能大赛活动总结
- 干货 | 使用云监控实现触发一个url调用
- 怎么看计算机电源型号,鲁大师怎么看电源 鲁大师电源参数查看方法