#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. 3DAY 用户管理

    0xff001用户/组管理 1.描述 用户和组: 系统上的每一个进程(运行程序)都是作为一个特定的用户运行的 每个文件都由特定的用户拥有 对文件和目录的访问受到用户的限制 与正在运行的进程相关联的用户 ...

  2. 学习MeteoInfo二次开发教程(九)

    最终的MaskOut功能未能实现 另外,一个有用的,在指定位置显示图片: legend.MarkerType = MarkerType.Image; legend.ImagePath = " ...

  3. factory di

    services.AddScoped(typeof(Test)); //services.AddScoped<Test>() // .AddScoped<ITest, Test> ...

  4. 对Unity一个Shader编译Bug的分析(Unrecognized sampler 'samplerunity_lightmap)

    写在前面 Unity的用户量越来越大,越来越有钱,这几年摊子也铺的越来越大,所以各个版本总是有很多Bug.对于一些Bug官方在ReleaseNote里的说明是很不详细的,而对于一些渲染相关的Bug,有 ...

  5. CSS3之动画模块实现云朵漂浮效果

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

  6. DOM随时记

    1.node-type 返回元素的节点类型:可以在标签上进行设置 node-type="item"   ---来自新浪微博的首页写法

  7. Android 开发 实现文本搜索功能

    核心逻辑方法: /** * 搜索item * @param searchContent 需要搜索的文本内容 */ public void searchItem(String searchContent ...

  8. 纠结了一下午的问题:运行opencv的HoughLinesP函数出错

    问题描述:检测出的直线数量显然不对,非常巨大.程序运行崩溃. 解决办法:在添加附加依赖项时,Dubug模式只添加opencv_world310d.lib,Release模式下只添加opencv_wor ...

  9. java枚举变量反解析用法

    最近常常有一些项目需要给枚举设值一个int值,以及对int值进行反解析出枚举类型,代码如下: public enum MatchResultEnum { /** * 赢 */ WIN(0), /** ...

  10. web跨域问题(No 'Access-Control-Allow-Origin'..)

    1. 问题 angular开发中连接java服务时出现跨域问题(No 'Access-Control-Allow-Origin'..). 如下图 解决方法 2,原因分析 这个与安全机制有关,默认情况下 ...