IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 词法分析器 -> 正文阅读

[数据结构与算法]词法分析器

1. 实验要求

手工设计c语言的词法分析器(可以式c语言子集)
处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中

2. 分析与设计

2.1 构造c语言子集

第一类:标识符 letter(letter | digit)* 无穷集
第二类:常数 (digit)+ 无穷集
第三类:保留字
main,int,char,if,else,for,while
第四类:界符 () { } [ ] , ;
第五类:运算符 <、<=、>、>=、=、+、-、*、/,==

2.2 单词符号表

在这里插入图片描述

2.3 状态转换图

在这里插入图片描述

3. 程序描述

3.1 数据结构

typedef struct 
{
	string code;//种别码
	string attr;//属性值
}node;//返回的二元组

3.2 主要函数

bool isdigit(char c);//判断是不是数字
bool ischar(char s);//判断是不是字符
bool isremain(string s);//判断是不是保留字
string read_filter(char *filename);//从文件中读取字符串并将字符串中无用的符号过滤掉
queue<node> LEX(string s);//词法分析
void print(queue<node> res);//打印词法分析结果,存放于文件中

3.3 算法描述

1.打开源文件source.txt,读取文件所有内容,存放在string s中。
2.对读取的文件进行预处理,从头到尾进行扫描,去除//注释的内容,以及换行符、回车符、制表符。
3.创建队列res(元素为node),用于返回分析结果。
4.对s每个字符从头到尾进行扫描
若当前的字符是空格,则继续扫描下一个字符。
若不是空格:
判断字符是不是字母,若是则进行标识符和保留字的识别;
若这个字符为数字,则进行数字的判断。
否则,依次对这个字符可能的情况进行判断。
每次成功识别了一个单词后,创建新的node t,将单词种别码和单词属性值存入其中,然后将t加入队列res中。
5.将结果存入result.txt文件中

4. 运行测试

在这里插入图片描述

5. 源代码

#include <iostream>
#include <string>
#include <vector>
#include<queue>
#include <fstream>
#include <iomanip>
using namespace std;
typedef struct 
{
	string code;//种别码
	string attr;//属性值
}node;
string remained[7]={"main","int","char","if","else","for","while"};//保留字
bool isdigit(char c);//判断是不是数字
bool ischar(char s);//判断是不是字符
bool isremain(string s);//判断是不是保留字
string read_filter(char *filename);//从文件中读取字符串并将字符串中无用的符号过滤掉
queue<node> LEX(string s);//词法分析
void print(queue<node> res);//打印词法分析结果,存放于文件中

//判断是不是数字
bool isdigit(char c)
{
	if(c>='0'&&c<='9')
		return 1;
	return 0;
}

//判断是不是字符
bool ischar(char c)
{
	if(c>='a'&&c<='z'||c>='A'&&c<='Z')
		return 1;
	return 0;
}

//判断是不是保留字
bool isremain(string s)
{
	for(int i=0;i<7;i++)
	{
		if(s==remained[i])
			return 1;
	}
	return 0;
}

//从文件中读取字符串并将字符串中无用的符号过滤掉
string read_filter(string filename)
{
	string s="";
	ifstream infile;
	infile.open(filename);
	while(!infile.eof())
	{
		char temp[90];
		infile.getline(temp,80);
		s+=temp;
		s+='\n';
	}
	string res="";
	int len=s.length ();
	for(int i=0;i<len-1;i++)
	{
		if(s[i]=='/'&&s[i+1]=='/')
		{
			while(s[i]!='\n')
			{
				i++;
			}
		}
		if(s[i]!='\n'&&s[i]!='\t'&&s[i] != '\r')
			res+=s[i];
	}
	cout<<res;
	return res;
}

//词法分析
queue<node> LEX(string s)
{
	queue<node> res;
	int len=s.length();
	node t;
	for(int i=0;i<len;i++)
	{
		if(s[i]!=' ')
		{
			string temp="";
			if(isdigit(s[i]))//判断是否为整型数字
			{
				temp+=s[i];
				i++;
				while(isdigit(s[i]))
				{
					temp+=s[i];
					i++;
				}
				i--;//返回最后字符
				t.code="2";t.attr =temp;
				res.push(t);//插入到返回结果中
			}
			else if(ischar(s[i]))//判断是否是保留字或者标识符
			{
				temp+=s[i];
				i++;
				while(ischar(s[i])||isdigit(s[i]))
				{
					temp+=s[i];
					i++;
				}
				i--;//返回最后字符
				if(isremain(temp))
				{
					t.code=temp;t.attr ="--";
					res.push(t);
				}
				else
				{	
					t.code="1";t.attr =temp;
					res.push(t);
				}
			}
			else
			{
				switch(s[i])
				{
				case '(':{t.code="10";t.attr ="(";res.push(t);break;}
				case ')':{t.code="11";t.attr =")";res.push(t);break;}
				case '{':{t.code="12";t.attr ="{";res.push(t);break;}
				case '}':{t.code="13";t.attr ="}";res.push(t);break;}
				case '[':{t.code="14";t.attr ="[";res.push(t);break;}
				case ']':{t.code="15";t.attr ="]";res.push(t);break;}
                case ',':{t.code="16";t.attr =",";res.push(t);break;}
				case ';':{t.code="17";t.attr =";";res.push(t);break;}
			    case '<':{
					i++;
					if(s[i]=='=')
					{t.code="19";t.attr ="<=";res.push(t);break;}
					else
					{t.code="18";t.attr ="<";res.push(t);i--;break;}
						 }
				case '>':{
					i++;
					if(s[i]=='=')
					{t.code="21";t.attr =">=";res.push(t);break;}
					else
					{t.code="20";t.attr =">";res.push(t);i--;break;}
					}
				case '=':{
					i++;
					if(s[i]=='=')
					{t.code="23";t.attr ="==";res.push(t);break;}
					else
					{t.code="22";t.attr ="=";res.push(t);i--;break;}
					}
               case '+':{t.code="24";t.attr ="+";res.push(t);break;}
			   case '-':{t.code="25";t.attr ="-";res.push(t);break;}
               case '*':{t.code="26";t.attr ="*";res.push(t);break;}
               case '/':{t.code="27";t.attr ="/";res.push(t);break;}
			   default:{t.code="ERROR";t.attr ="--";res.push(t);}
				}
			}
		}
	}
	return res;
}

//将结果存放在文件"result.txt"中
void print(queue<node> res)
{
	ofstream out("result.txt",ios::out);
	int i=0;//控制输出格式
	while(!res.empty())
	{
		node temp;
		temp=res.front();
		res.pop();
		out<<setw(4)<<"( "<<setw(4)<<temp.code<<setw(4)<<","<<setw(4)<<temp.attr <<setw(4)<<" )";
		out<<"  ";
		i++;
		if(i%5==0)
			out<<endl;
	}
	out.close();
}
void main()
{
	string s;
	string filename="source.txt";
	s=read_filter(filename);
	
	queue<node> res=LEX(s);
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:31:37  更:2021-10-09 16:34:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:33:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码