#include <iostream>
#include <stdlib.h>
#include <stdio.h> using namespace std;
string KEYWORD[]={"if","else","void","return","while","then","for","do", //关键字
"int","char","double","float","case","cin","cout"};
char SEPARATER[]={';',',','{','}','[',']','(',')'}; //分隔符
char OPERATOR[]={'+','-','*','/','>','<','=','!'}; //运算符
char FILTER[]={' ','\t','\r','\n'}; //过滤符
const int IDENTIFIER=; //标识符值
const int CONSTANT=; //常数值
const int FILTER_VALUE=; //过滤字符值 /**判断是否为关键字**/
bool IsKeyword(string word){
for(int i=;i<;i++){
if(KEYWORD[i]==word){
return true;
}
}
return false;
}
/**判断是否为分隔符**/
bool IsSeparater(char ch){
for(int i=;i<;i++){
if(SEPARATER[i]==ch){
return true;
}
}
return false;
} /**判断是否为运算符**/
bool IsOperator(char ch){
for(int i=;i<;i++){
if(OPERATOR[i]==ch){
return true;
}
}
return false;
}
/**判断是否为过滤符**/
bool IsFilter(char ch){
for(int i=;i<;i++){
if(FILTER[i]==ch){
return true;
}
}
return false;
}
/**判断是否为大写字母**/
bool IsUpLetter(char ch){
if(ch>='A' && ch<='Z') return true;
return false;
}
/**判断是否为小写字母**/
bool IsLowLetter(char ch){
if(ch>='a' && ch<='z') return true;
return false;
}
/**判断是否为数字**/
bool IsDigit(char ch){
if(ch>='' && ch<='') return true;
return false;
}
/**返回每个字的值**/
template <class T>
int value(T *a,int n,T str){
for(int i=;i<n;i++){
if(a[i]==str) return i+;
}
return -;
}
/**词法分析**/
void analyse(FILE * fpin){
char ch=' ';
string arr="";
while((ch=fgetc(fpin))!=EOF){
arr="";
if(IsFilter(ch)){} //判断是否为过滤符
else if(IsLowLetter(ch)){ //判断是否为关键字
while(IsLowLetter(ch)){
arr += ch;
ch=fgetc(fpin);
}
//fseek(fpin,-1L,SEEK_CUR);
if(IsKeyword(arr)){
printf("%3d ",value(KEYWORD,,arr));
cout<<arr<<" 关键字"<<endl;
}
else
{
printf("%3d ",IDENTIFIER);
cout<<arr<<" 标识符"<<endl;
}
}
else if(IsDigit(ch)){ //判断是否为数字
while(IsDigit(ch)||(ch=='.'&&IsDigit(fgetc(fpin)))){
arr += ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
printf("%3d ",CONSTANT);
cout<<arr<<" 整形数"<<endl;
}
else if(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'){
while(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'||IsDigit(ch)){
arr += ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
printf("%3d ",CONSTANT);
cout<<arr<<" 标识符"<<endl;
}
else switch(ch){
case '+':
case '-':
case '*':
case '/':
case '>':
case '<':
case '=':
case '!':
{
arr += ch;
printf("%3d ",value(OPERATOR,,*arr.data()));
cout<<arr<<" 运算符"<<endl;
break;
}
case ';':
case ',':
case '(':
case ')':
case '[':
case ']':
case '{':
case '}':
{
arr += ch;
printf("%3d ",value(SEPARATER,,*arr.data()));
cout<<arr<<" 分隔符"<<endl;
break;
}
default :cout<<"\""<<ch<<"\":无法识别的字符!"<<endl;
}
} }
int main()
{
char inFile[];
FILE *fpin;
cout<<"请输入源文件名(包括路径和后缀):";
while(true){
cin>>inFile;
if((fpin=fopen(inFile,"r"))!=NULL)
break;
else{
cout<<"文件名错误!"<<endl;
cout<<"请输入源文件名(包括路径和后缀):";
} }
cout<<"------词法分析如下------"<<endl;
analyse(fpin);
return ;
}

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. CCF2017-9-1

    题目: 分析:将所有可能列出来,80可以分为8个10块(这时候最多也是8个),在这种情况下,可以分为2个30块, 3个循环嵌套,判断是不是输入的总钱数,因为不是所有的都是加起来是80,就是分为买多少个 ...

  2. 搭建Hadoop

    最近开始学习hadoop现实是完全分布式 安利大佬博客学习 https://blog.csdn.net/downing114/article/details/60956979 在Ubuntu上学习  ...

  3. flask+redis实现抢购(秒杀)功能

    今天面试了 一家非常高大上的公司,问了我关于redis的实用性问题,但是答的不是很好,所以下午通过再次学习 redis,实现相关实用性功能的一种. 对于抢购功能,难点在于 抢购时 由于高并发请求,导致 ...

  4. efcore migration

    实体------->migration------->db ---------------------------------------------------------------- ...

  5. Javascript 京东轮播图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  6. Mysql时间差计算

    Mysql如何计算两个时间字段的差值?可用函数 TIMESTAMPDIFF() ----------------------------- TIMESTAMPDIFF函数,有参数设置,可以精确到天(D ...

  7. centos7 设置nginx和php开机自启动

    nginx开机自启动 首先我是源码安装的,需要手动建立nginx.service服务文件 cd /lib/systemd/system touch nginx.service nginx.servic ...

  8. python 使用多进程打开多个cmd窗口,并在子进程结束之后关闭cmd窗口

    额,我想表达的是使用os.system()打开另一个可执行文件,然后等待其结束,关闭cmd窗口 主要是我突发奇想想装逼; 如果只是用multiprocessing库的多进程,然后输出信息的话,根本没法 ...

  9. 超详细的遗传算法(Genetic Algorithm)解析

    https://blog.csdn.net/u010451580/article/details/51178225 https://www.jianshu.com/p/c82f09adee8f 00 ...

  10. Dnsmasq 配置PXE批量安装系统

    以下测试都是基于centos 7下的环境 需要安装的软件为 nginx 用来下载ks.cfg和系统镜像文件用的,也可以用ftp服务器来代替 dnsmasq 提供dhcp服务和tftp服务,也可以单独去 ...