#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++实现的更多相关文章

  1. sizzle分析记录:词法分析器(tokenize)

    词法分析器(tokenize)? 词法分析器又称扫描器.词法分析是指将我们编写的文本代码流解析为一个一个的记号,分析得到的记号以供后续语法分析使用. sizzle引入了tokenize这个概念,意义? ...

  2. C# 词法分析器(五)转换 DFA

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 在上一篇文章中,已经得到了与正则表达式等价的 NFA ...

  3. 用词法分析器Flex过滤日志

    每日构造中,我的项目中 Visual Studio 的 MakeFile 后会产生大量信息,如下 Microsoft (R) Visual Studio Version 10.0.40219.1.Co ...

  4. Atitit 词法分析器的设计最佳实践说明attilax总结

    Atitit 词法分析器的设计最佳实践说明attilax总结 1.1. 手写的优点:代码可读,对源代码中的各种错误给出友好的提示信息,用户体验高,1 1.2. 使用状态表比较简单,dfa比较麻烦1 1 ...

  5. Atitit 发帖机系列(8)  词法分析器v5 版本新特性说明)

    Atitit 发帖机系列(8)  词法分析器v5 版本新特性说明) v5  增加对sql单引号的内部支持.可以作为string 结构调整,使用递归法重构循环发..放弃循环发. V4 java dsl词 ...

  6. 兼容90%标准C的词法分析器

    不能分词八进制和数字类型加前/后缀的情况 拿这个词法分析器跑了一遍整个Nginx源码,基本都能正确的分出结果,后面有测试例子~ #ifndef _STATES_H_ #define _STATES_H ...

  7. 编译原理(简单自动词法分析器LEX)

    编译原理(简单自动词法分析器LEX)源程序下载地址:  http://files.cnblogs.com/files/hujunzheng/%E6%B1%87%E7%BC%96%E5%8E%9F%E7 ...

  8. java简单词法分析器(源码下载)

    java简单词法分析器 : http://files.cnblogs.com/files/hujunzheng/%E7%AE%80%E5%8D%95%E8%AF%8D%E6%B3%95%E5%88%8 ...

  9. C# 词法分析器(一)词法分析介绍 update 2014.1.8

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 虽然文章的标题是词法分析,但首先还是要从编译原理说开 ...

  10. C# 词法分析器(二)输入缓冲和代码定位

    系列导航 (一)词法分析介绍 (二)输入缓冲和代码定位 (三)正则表达式 (四)构造 NFA (五)转换 DFA (六)构造词法分析器 (七)总结 一.输入缓冲 在介绍如何进行词法分析之前,先来说说一 ...

随机推荐

  1. HITICS || 2018大作业 程序人生 Hello's P2P

    摘  要 本文通过分析一个hello.c的完整的生命周期,从它开始被编译,到被汇编.链接.在进程中运行,讲解了Linux计算机系统执行一个程序的完整过程. 关键词:操作系统,进程,程序的生命周期 目 ...

  2. java在线聊天项目 使用SWT快速制作登录窗口,可视化窗口Design 更换窗口默认皮肤(切换Swing自带的几种皮肤如矩形带圆角)

    SWT成功激活后 new一个JDialog 调整到Design视图 默认的视图模式是BorderLayout,无论你怎么拖拽,只能放到东西南北中的位置上 所以,我们把视图模式调整为AbsoluteLa ...

  3. ios开发--常用的高效开发的宏

    本次在做项目的时候使用了下面的一些宏定义 以及 建立宏定义的一些规则.虽然只用了其中的一点点,但是还是极大的提高了开发效率.. 将这些宏放到一个头文件里然后再放到工程中,在需要使用这些宏定义的地方体检 ...

  4. Linux基础学习-数据备份工具Rsync

    数据备份工具rsync 作为一个系统管理员,数据备份是非常重要的,如果没有做好备份策略,磁盘损坏了,那么你的数据将全部丢失,所以在日常的维护工作中,一定要时刻牢记给数据做备份. rsync不仅可以可以 ...

  5. vue中 表头th 合并单元格,且表格列数不定的动态渲染方法

    吐槽 今天,在vue中遇到 复杂表格的渲染 ,需要合并表头的单元格,且合并单元格的那列还是动态数据,也就是说你不知道会有多少组要合并起来,哎,我也有点说不清楚,废话不多说了,看代码把: 代码示例 da ...

  6. url编码&&PHP大法&&这个看起来有点简单&&HTML 中有用的字符实体

    URL编码 Url编码通常也被称为百分号编码(Url Encoding,also known as percent-encoding),是因为它的编码方式非常简单,使用%百分号加上两位的字符——012 ...

  7. C盘清理小技巧

    步骤/方法 1 1  关闭休眠功能,在开始菜单的运行里输入powercfg -h off 指令,关闭休眠,此文件实际大小和物理内存是一样的,大约可以为C盘释放1-3G的空间. 2 2  设置虚拟内存: ...

  8. BZOJ 4557: [JLoi2016]侦察守卫

    题目大意:每个点有一个放置守卫的代价,同时每个点放置守卫能覆盖到的距离都为d,问覆盖所有给定点的代价是多少. 题解: 树形DP f[x][y]表示x子树中所有点都已经覆盖完,并且x还能向上覆盖y层的最 ...

  9. lucene segment的产生,flush, commit与es的refresh,flush

    1 segment的产生 当索引一个文档时,如果存在空闲的segment(未被其他线程锁定),则取出空闲segment list中的最后一个segment(LIFO),并锁定,将文档索引至该segme ...

  10. 【20】display,float,position的关系

    [20]display,float,position的关系 如果display为none,元素不显示. 否则,如果position值为absolute或者fixed,元素绝对定位,float的计算值为 ...