词法分析器 /c++实现
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int line=1,row=1;
char c;
map<char,int>ma;
struct kind
{
string na; //单词
int num; //内码
string type; //类型
int l,r; //行列数
};
vector<kind>res; //视图表
int tree[10000][30];int numv=0;int w[10000];
int key=0; int flag=0;
void insert(string s) //关键词trie树
{
int u=0;
for(int i=0;i<s.size();i++)
{
if(tree[u][s[i]-'a']==0)
tree[u][s[i]-'a']=++numv;
u=tree[u][s[i]-'a'];
}
w[u]=key++;
}
void f1(char &c) // 关键字标识符分析器
{
int mark=1;
string s;
s+=c;
int u=0;
if(tree[u][c-'a']!=0)
u=tree[u][c-'a'];
else mark=0;
while(c=getchar())
{
if(!(c>='a'&&c<='z'))
if(c!='_')
if(!(c>='0'&&c<='9'))
break;
if(mark==1)
{
if(tree[u][c-'a']!=0)
u=tree[u][c-'a'];
else mark=0;
}
s+=c;
}
kind t;
t.na=s;
t.l=line;
t.r=row;
if(mark==0)
{
t.num=flag++;
t.type=" 标志符";
}
else
{
t.num=w[u];
t.type=" 关键字";
}
res.push_back(t);
return ;
}
void f2(char &c) //数字分析器
{
string s;
s+=c;
c=getchar();
while(c>='0'&&c<='9')
{
s+=c;
c=getchar();
}
int mark=1;
while(c>='a'&&c<='z')
{s+=c;mark=0;c=getchar();}
kind t;
t.na=s;
t.l=line;
t.r=row;
if(mark==1)
{
char *p;
strcpy(p,s.c_str());
t.num=atoi(p);
t.type=" 数字";
}
else
{
t.type=" error";
t.num=0;
}
res.push_back(t);
return ;
}
void f3(char &c) //分界符、运算符等其他分析器
{
string s;
kind t;
t.l=line;t.r=row;
if(ma.find(c)!=ma.end())
{
t.na+=c;
if(ma[c]<=8)t.type=" 分界符";
else t.type=" 运算符";
t.num=ma[c];
c=getchar();
}
else
{
t.type=" 关系运算符";
if(c=='>')
{
c=getchar();
if(c=='=')
{
t.na=">=";
t.num=1;
c=getchar();
}
else
{
t.na=">";
t.num=2;
}
}
else if(c=='<')
{
c=getchar();
if(c=='=')
{
t.na="<=";
t.num=3;
c=getchar();
}
else if(c=='>')
{
t.na="<>";
t.num=4;
c=getchar();
}
else
{
t.na="<";
t.num=5;
}
}
else if(c=='=')
{
t.na="=";
t.num=6;
c=getchar();
}
}
res.push_back(t);
return ;
}
int main() //总控程序
{
ma['[']=1;ma[']']=2;ma[',']=3;ma[';']=4;ma['(']=5;ma[')']=6;ma['{']=7;ma['}']=8;
ma['+']=9;ma['-']=10;ma['*']=11;ma['/']=12;ma['%']=13;
string s;
while(s!="end")
{
cin>>s;
insert(s);
}
getchar();
cout<<"请输入语句:"<<endl;
c=getchar();
while(1)
{
if(c=='@')break;
while(c==' '){c=getchar();row++;}
if(c>='a'&&c<='z')
f1(c);
else if(c>='0'&&c<='9')
f2(c);
else
f3(c);
row++;
if(c=='\n')
{
line++;
row=1;
c=getchar();
}
}
cout<<"单词"<<'\t'<<'\t'<<"二元序列"<<'\t'<<'\t'<<"类型"<<'\t'<<'\t'<<"位置(行,列)"<<endl;
for(int i=0;i<res.size();i++)
{
cout<<res[i].na<<'\t'<<'\t'<<"("<<res[i].num<<","<<res[i].na<<")"<<'\t'<<'\t'<<res[i].type<<'\t'<<'\t'<<"("<<res[i].l<<","<<res[i].r<<")"<<endl;
} }
测试:
if while int char else then do
end
int a=10;
int b=11;
int s=0;
if(a>=10)
{
s=a+b%2;
}
else
{
s=a-b*a/11;
}
int 3b;
@
词法分析器 /c++实现的更多相关文章
- sizzle分析记录:词法分析器(tokenize)
词法分析器(tokenize)? 词法分析器又称扫描器.词法分析是指将我们编写的文本代码流解析为一个一个的记号,分析得到的记号以供后续语法分析使用. sizzle引入了tokenize这个概念,意义? ...
- C# 词法分析器(五)转换 DFA
系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 在上一篇文章中,已经得到了与正则表达式等价的 NFA ...
- 用词法分析器Flex过滤日志
每日构造中,我的项目中 Visual Studio 的 MakeFile 后会产生大量信息,如下 Microsoft (R) Visual Studio Version 10.0.40219.1.Co ...
- Atitit 词法分析器的设计最佳实践说明attilax总结
Atitit 词法分析器的设计最佳实践说明attilax总结 1.1. 手写的优点:代码可读,对源代码中的各种错误给出友好的提示信息,用户体验高,1 1.2. 使用状态表比较简单,dfa比较麻烦1 1 ...
- Atitit 发帖机系列(8) 词法分析器v5 版本新特性说明)
Atitit 发帖机系列(8) 词法分析器v5 版本新特性说明) v5 增加对sql单引号的内部支持.可以作为string 结构调整,使用递归法重构循环发..放弃循环发. V4 java dsl词 ...
- 兼容90%标准C的词法分析器
不能分词八进制和数字类型加前/后缀的情况 拿这个词法分析器跑了一遍整个Nginx源码,基本都能正确的分出结果,后面有测试例子~ #ifndef _STATES_H_ #define _STATES_H ...
- 编译原理(简单自动词法分析器LEX)
编译原理(简单自动词法分析器LEX)源程序下载地址: http://files.cnblogs.com/files/hujunzheng/%E6%B1%87%E7%BC%96%E5%8E%9F%E7 ...
- java简单词法分析器(源码下载)
java简单词法分析器 : http://files.cnblogs.com/files/hujunzheng/%E7%AE%80%E5%8D%95%E8%AF%8D%E6%B3%95%E5%88%8 ...
- C# 词法分析器(一)词法分析介绍 update 2014.1.8
系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 虽然文章的标题是词法分析,但首先还是要从编译原理说开 ...
- C# 词法分析器(二)输入缓冲和代码定位
系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 一.输入缓冲 在介绍如何进行词法分析之前,先来说说一 ...
随机推荐
- HITICS || 2018大作业 程序人生 Hello's P2P
摘 要 本文通过分析一个hello.c的完整的生命周期,从它开始被编译,到被汇编.链接.在进程中运行,讲解了Linux计算机系统执行一个程序的完整过程. 关键词:操作系统,进程,程序的生命周期 目 ...
- java在线聊天项目 使用SWT快速制作登录窗口,可视化窗口Design 更换窗口默认皮肤(切换Swing自带的几种皮肤如矩形带圆角)
SWT成功激活后 new一个JDialog 调整到Design视图 默认的视图模式是BorderLayout,无论你怎么拖拽,只能放到东西南北中的位置上 所以,我们把视图模式调整为AbsoluteLa ...
- ios开发--常用的高效开发的宏
本次在做项目的时候使用了下面的一些宏定义 以及 建立宏定义的一些规则.虽然只用了其中的一点点,但是还是极大的提高了开发效率.. 将这些宏放到一个头文件里然后再放到工程中,在需要使用这些宏定义的地方体检 ...
- Linux基础学习-数据备份工具Rsync
数据备份工具rsync 作为一个系统管理员,数据备份是非常重要的,如果没有做好备份策略,磁盘损坏了,那么你的数据将全部丢失,所以在日常的维护工作中,一定要时刻牢记给数据做备份. rsync不仅可以可以 ...
- vue中 表头th 合并单元格,且表格列数不定的动态渲染方法
吐槽 今天,在vue中遇到 复杂表格的渲染 ,需要合并表头的单元格,且合并单元格的那列还是动态数据,也就是说你不知道会有多少组要合并起来,哎,我也有点说不清楚,废话不多说了,看代码把: 代码示例 da ...
- url编码&&PHP大法&&这个看起来有点简单&&HTML 中有用的字符实体
URL编码 Url编码通常也被称为百分号编码(Url Encoding,also known as percent-encoding),是因为它的编码方式非常简单,使用%百分号加上两位的字符——012 ...
- C盘清理小技巧
步骤/方法 1 1 关闭休眠功能,在开始菜单的运行里输入powercfg -h off 指令,关闭休眠,此文件实际大小和物理内存是一样的,大约可以为C盘释放1-3G的空间. 2 2 设置虚拟内存: ...
- BZOJ 4557: [JLoi2016]侦察守卫
题目大意:每个点有一个放置守卫的代价,同时每个点放置守卫能覆盖到的距离都为d,问覆盖所有给定点的代价是多少. 题解: 树形DP f[x][y]表示x子树中所有点都已经覆盖完,并且x还能向上覆盖y层的最 ...
- lucene segment的产生,flush, commit与es的refresh,flush
1 segment的产生 当索引一个文档时,如果存在空闲的segment(未被其他线程锁定),则取出空闲segment list中的最后一个segment(LIFO),并锁定,将文档索引至该segme ...
- 【20】display,float,position的关系
[20]display,float,position的关系 如果display为none,元素不显示. 否则,如果position值为absolute或者fixed,元素绝对定位,float的计算值为 ...