词法分析器

实验要求

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 do
2、根据状态图,设计词法分析函数int scan( ),完成以下功能:
1) 从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,
2) 以二元式形式输出单词<单词种类,单词属性>
其中单词种类用整数表示:
0:标识符
1:十进制整数
2:八进制整数
3:十六进制整数
运算符和界符,关键字采用一字一符,不编码
其中单词属性表示如下:
标识符,整数由于采用一类一符,属性用单词表示
运算符和界符,关键字采用一字一符,属性为空

实验分析

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 do
由于实验描述中已经包含相关的正规式描述,所以我们并不需要做过多处理。
2、 变换后的状态图;

3、 词法分析程序的数据结构与算法。

以上为整体代码框架部分,在代码的构造函数中读入输入文件中的数据,单行读入,将读入的串作为参数调用scan函数扫描。通过判断每一个单词是iscal(运算符界符),是isKey(关键字),是isTen(十进制),是isEight(八进制),是isSixteen(十六进制)来区分单词,而标识符直接使用isalpha()实现判断。同时还有一个结构体Twotuples用于记录结果,内含有两个分量, 就是结果显示左右部分。

实验代码

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iomanip>
using namespace std;
const int maxn = 1e4;
const int maxlen = 1e4;
class lexical {
private:char operate[10][10] = { "+","-","*","/",">","<","=","(",")",";" };const int rowope = 10;char keyword[5][10] = { "if","then","else","while","do" };const int rowkey = 5;struct Twotuples {char kind[10];char proper[10];}tuples[maxlen];string filename;
public:bool isCal(char *s, int &length) {char sub[100];for (int i = 0; i < rowope; i++) {int len = strlen(operate[i]);strncpy(sub, s, len);sub[len] = '\0';if (strcmp(sub, operate[i]) == 0) {length = len;return true;}}return false;}bool isKey(char *s, int &length) {char sub[100];int num = 0;while (isalpha(*(s + num))) {num++;}length = num;for (int i = 0; i < rowkey; i++) {strncpy(sub, s, length);sub[length] = '\0';if (strcmp(sub, keyword[i]) == 0 && !isalpha(*(s + length))) {return true;}}return false;}bool isTen(char *s, int &length) {if (s[0] == '0'&&!isdigit(s[1]) && s[1] != 'x') {length = 1;return true;}elseif (s[0] >= '1'&&s[0] <= '9') {int num = 0;while (isdigit(*(s + num))) {num++;}length = num;return true;}return false;}bool isEight(char *s, int &length) {if (s[0] == '0' && (s[1] >= '1'&&s[1] <= '7')) {int num = 0;while (s[num] >= '0'&&s[num] <= '7') {num++;}length = num;return true;}return false;}bool isSixteen(char *s, int &length) {if (s[0] == '0' && s[1] == 'x' && ((s[2] >= '0'&&s[2] <= '9') || (s[2] >= 'a'&&s[2] <= 'f'))) {int num = 2;while ((s[num] >= '0'&&s[num] <= '9') || (s[num] >= 'a'&&s[num] <= 'f')) {num++;}length = num;return true;}return false;}void scan(char *str, int &p1, int &p2) {int len = 0;char str_[] = "-";char sub[100];//运算符和界符if (isCal(str + p1, len)) {strncpy(sub, str + p1, len);sub[len] = '\0';strcpy(tuples[p2].kind, sub);strcpy(tuples[p2].proper, str_);p1 += len;p2++;}//关键字if (isKey(str + p1, len)) {strncpy(sub, str + p1, len);sub[len] = '\0';strcpy(tuples[p2].kind, sub);strcpy(tuples[p2].proper, str_);p1 += len;p2++;}//标识符if (isalpha(*(str + p1))) {int len = 0;while (isalpha(*(str + p1 + len)) || isdigit(*(str + p1 + len))) {len++;}strncpy(sub, str + p1, len);sub[len] = '\0';strcpy(tuples[p2].kind, "0");strcpy(tuples[p2].proper, sub);p1 += len;p2++;}//十进制数字if (isTen(str + p1, len)) {strncpy(sub, str + p1, len);sub[len] = '\0';strcpy(tuples[p2].kind, "1");strcpy(tuples[p2].proper, sub);p1 += len;p2++;}if (isEight(str + p1, len)) {strncpy(sub, str + p1 + 1, len - 1);sub[len - 1] = '\0';strcpy(tuples[p2].kind, "2");strcpy(tuples[p2].proper, sub);p1 += len;p2++;}if (isSixteen(str + p1, len)) {strncpy(sub, str + p1 + 2, len - 2);sub[len - 2] = '\0';strcpy(tuples[p2].kind, "3");strcpy(tuples[p2].proper, sub);p1 += len;p2++;}}lexical(string inputfile , string outputfile) {this->filename = inputfile;char *buffer = new char[maxlen];ifstream in(filename);if (!in.is_open()) {cout << "文件打开失败" << endl;exit(1);}in.getline(buffer, maxlen, '#');int len = strlen(buffer);bool flagend = false;for (int i = 0; i < strlen(buffer); i++) {if (buffer[i] == '#') {flagend = true;break;}}if (!flagend)buffer[len++] = '#';buffer[len] = '\0';cout << buffer << endl;int buf_ptr = 0;int tup_ptr = 0;while (true) {if (buffer[buf_ptr] == '#')break;if (buffer[buf_ptr] == ' ' || buffer[buf_ptr] == '\n') {buf_ptr++;continue;}if (buffer[buf_ptr] == '\t') {buf_ptr += 4;continue;}scan(buffer, buf_ptr, tup_ptr);}cout.setf(std::ios::left);ofstream out(outputfile);for (int i = 0; i < tup_ptr; i++) {out  << "<" << setw(5) << tuples[i].kind << "," << setw(5) << tuples[i].proper << ">" << endl;cout << "<" << setw(5) << tuples[i].kind << "," << setw(5) << tuples[i].proper << ">" << endl;}}
};
int main()
{string filename1 = "D:\\c++Project\\fundamentals_of_compiling\\Parsing\\test.txt";string filename2= "D:\\c++Project\\fundamentals_of_compiling\\Parsing\\out.txt";lexical *text = new lexical(filename1,filename2);system("pause");return 0;
}

编译原理-词法分析器相关推荐

  1. 【SEUSE】编译原理 - 词法分析器实验报告

    [SEU&SE]编译原理 - 词法分析器实验报告 README 一. 实验目的 二. 实验环境 1. 开发环境: 2. 运行环境 三. 实验内容 1. 主要内容 2. 主要功能 3. 种别码 ...

  2. 编译原理——词法分析器

    采用java图形化界面编写了java语言的词法分析器,该分析器可识别所有java关键字.软件工程课程中编译原理实验. Keyword.jvav package org.kyc.test1;public ...

  3. 编译原理--词法分析器(python语言实现)

    词法分析器 最近在学习编译原理.由于实验要求有词法分析器,这里我就先记录一下词法分析器实现过程以及具体思路. 目标语言 此处我选择的目标语言是c语言的子集来进行词法分析. 实现语言 此处我选用的语言是 ...

  4. 编译原理词法分析器的c++实现

    一.题目的理解和说明 编译原理这门课是计算机专业的核心课程之一,是一门研究软件是什么,为什么可以运行,以及怎么运行的学科.编译系统的改进将会直接对其上层的应用程序的执行效率,执行原理产生深刻的影响.编 ...

  5. 编译原理———词法分析器

    1.目的 设计并实现一个包含预处理功能的词法分析程序,加深对编译中词法分析过程的理解. 2.实现功能:词法分析 输入:所给文法的源程序字符串. 输出:二元组(syn,token或sum)构成的序列.其 ...

  6. 南华大学编译原理----词法分析器的设计与实现、语法分析器的设计与实现

    下载链接:(各位同学不需要充钱哈,这种我也没有收益,去淘宝上面找个代下,大概0.5元就能下载实验报告,用来给同学们参考,下载积分不是我设置的,是网站自己默认的) ------------------- ...

  7. 编译原理——词法分析器的设计

    两种设计方案以及各自优缺点 我们先学手工构造 词法分析器手工构造 关系运算符的手工构造: 上面这个图其实我有点疑惑,下面说一下,我自己的理解 C语言中的关系运算符,有<. <=. > ...

  8. 编译原理—词法分析器(Java)

    1.当运行程序时,程序会读取项目下的program.txt文件 2. 程序将会逐行读取program.txt中的源程序,进行词法分析,并将分析的结果输出. 3. 如果发现错误,程序将会中止读取文件进行 ...

  9. 编译原理词法分析器(C/C++)

    前言&思路 词法分析器不用多说,一开始我还不知道是什么样的,看了下别人的博客,再看看书,原来是输出二元组,这不就是字符串操作嘛.然后细看几篇博客,发现大都是用暴力判断来写的.我对代码重复性比较 ...

最新文章

  1. Kona 8:鹅厂基于OpenJDK开源的JDK
  2. 数据库报错1046-No database selected
  3. 其他OJ 树型DP 选课
  4. element-ui中单独引入Message组件的问题
  5. pushState 和 replaceState
  6. 软考自查:数据库设计
  7. 深入理解Java中的String
  8. 计算机网络中 子网掩码的算法,[网络天地]子网掩码快速算法(转载)
  9. html用转义字符画菱形,JavaScript生成字符画(ASCII Art)
  10. 【自然语言处理工具箱 LTP 】pyltp 使用教程
  11. 多功能多接口带头像挂件制作微信小程序源码
  12. 直线端点画垂线lisp_AutoCAD中利用AutoLISP开发小程序,实现快速画直线对称中心线...
  13. mac 系统 突破百度网盘网速限制
  14. 在yandex投放广告的话,需要注册俄罗斯常用的域名吗?
  15. flutter中的常见色值设置
  16. node-red教程7.3 常见的显示型仪表板控件应用
  17. android自动切换暗色,Android 适配深色模式的总结
  18. 学习英文之社区,博客及源码
  19. faspeed是什么意思_COCOS学习笔记--变速动作Speed和ActionEase
  20. 进制转换算法 (C语言实现一个简单的二进制转换工具) ------- 算法笔记010

热门文章

  1. CodeForces - 1646E Power Board (思维,数学)
  2. Java Message Servicec - ActiveMQ
  3. 运动学习与控制-学习笔记(三)——运动控制理论
  4. C# 经常忘 该记记
  5. 微服务ServiceMesh及三种模式介绍
  6. 软考 案例分析__预测
  7. Java架构师之路:从Java码农到年薪八十万的架构师
  8. 2018最新苹果公司开发者账号设置税务
  9. 健身管理系统 -像微信一样简单的智能健身房管理系统
  10. 【springboot】sse接口