C语言词法分析:C#源码
今天继续研究代码解析的算法
这个是算法流程图

有图解可能更直观一点;
以下是c#源码:
using System;2
using System.IO;3
using System.Text;4
using System.Windows.Forms;5
using System.Collections;6

7

namespace CodeFormatter
{8

/**//// <summary>9
/// CodeFormatterFactory 的摘要说明。10
/// c 代码解析,不支持中文11
/// </summary>12

public class CodeFormatterFactory
{13

/**//*源代码*/14
private string sourceCode = "";15

16

/**//*C语言所有关键字,共32个*/17
ArrayList KeyWordList = new ArrayList();18

19

/**//*运算、限界符*/20
ArrayList LimitList = new ArrayList();21

22

/**//*常量表*/23
ArrayList ConstList = new ArrayList();24

25

/**//*标识符*/26
ArrayList IdentifierList = new ArrayList();27

28

/**//*输出*/29
ArrayList OutputList = new ArrayList();30

31

public CodeFormatterFactory()
{32
//33
// TODO: 在此处添加构造函数逻辑34
//35
init();36
}37

38

public string SourceCode
{39

get
{return this.sourceCode;}40

set
{this.sourceCode =value;}41
}42

43

public string ParseMessages
{44

get
{45
string pm = "";46

47
IEnumerator ie = this.OutputList.GetEnumerator();48
while ( ie.MoveNext() )49
pm += ie.Current.ToString() + "\r\n";50
return pm;51
}52
}53

54

private void init()
{55

/**//*C语言所有关键字,共32个*/56

string[] key=new string[]
{" ","auto","break","case","char","const","continue","default","do","double",57
"else","enum","extern","float","for","goto","if","int","long","register",58
"return","short","signed","sizeof","static","struct","switch","typedef",59
"union","unsigned","void","volatile","while"};60

/**//*运算、限界符*/61

string[] limit=new string[]
{" ","(",")","[","]","->",".","!","++","--","&","~",62
"*","/","%","+","-","<<",">>","<","<=",">",">=","==","!=","&&","||",63
"=","+=","-=","*=","/=",",",";","{","}","#","_","'"};64

65
this.KeyWordList.Clear();66
this.KeyWordList.TrimToSize();;i<key.Length;i++)
68
this.KeyWordList.Add(key[i]);69

70
this.LimitList.Clear();71
this.LimitList.TrimToSize();;i<limit.Length;i++)
73
this.LimitList.Add(limit[i]);74

75
this.ConstList.Clear();76
this.ConstList.TrimToSize();77

78
this.IdentifierList.Clear();79
this.IdentifierList.TrimToSize();80

81
this.OutputList.Clear();82
this.OutputList.TrimToSize();83
}84

85

/**//*******************************************86
* 十进制转二进制函数87
*******************************************/88

private string dtb(string buf)
{];
90
string binary = "";;
92

93

/**//*先将字符转化为十进制数*/94

try
{95
val = Convert.ToInt32(buf);96

}catch
{;
98
}99

)
{
return(val.ToString());
}
;
)
{;
;
}
binary = "";;j++)
);

return(binary);
}

/**//*******************************************
* 根据不同命令查表或造表函数
*******************************************/
private int find(string buf,int type,int command)
{ ;
string temp;
IEnumerator ie = null;
ArrayList al = null;
switch(type)
{://关键字表
ie = this.KeyWordList.GetEnumerator();
break;://标识符表
ie = this.IdentifierList.GetEnumerator();
break;://常数表
ie = this.ConstList.GetEnumerator();
break;://运算、限界符表
ie = this.LimitList.GetEnumerator();
break;
} 
if(ie!=null)
while (ie.MoveNext())
{
temp = ie.Current.ToString();
if(temp.Trim().ToLower()==buf.Trim().ToLower())
{
return number;
}
number ++;
}
)
{
/**//*找不到,当只需查表,返回0,否则还需造表*/;
}

switch(type)
{: al = this.KeyWordList;break;
: al = this.IdentifierList;break;
: al = this.ConstList;break;
: al = this.LimitList;break;
}
if(al!=null)
al.Add(buf);
;
}
/**//*******************************************
* 数字串处理函数
*******************************************/
private void cs_manage(string buffer)
{
string binary = dtb(buffer););
this.OutputList.Add(String.Format("{0}\t\t\t3\t\t\t{1}",buffer,result));
}

/**//*******************************************
* 字符串处理函数
*******************************************/
private void ch_manage(string buffer)
{);
)
{
this.OutputList.Add(String.Format("{0}\t\t\t1\t\t\t{1}",buffer,result));
}else
{);
this.OutputList.Add(String.Format("{0}\t\t\t2\t\t\t{1}",buffer,result));
}
}

/**//*******************************************
* 出错处理函数
*******************************************/
private void er_manage(char error,int lineno)
{
this.OutputList.Add(String.Format("错误关键字: {0} ,所在行: {1}",error,lineno));
}

/**//*******************************************
* 转换Char数组为string
******************************************/
private string joinString(char[] array,int Length)
{
string s = "";)
;i<Length;i++)
{
if(array[i]!='\0')
{
s+=array[i];
}else
{
break;
}
}
return s;
}

private char getchc(ref int n)
{
char[] c = sourceCode.ToCharArray();
if(n<c.Length)
{
char r = c[n];
n++;
return r;
}];
}
/**//*******************************************
* 扫描程序
********************************************/
public void Parse()
{
//StreamWriter fpout = null;
char ch ;;
;
];
string word= "";

/**//*按字符依次扫描源程序,直至结束*/;

)
{;
ch = getchc(ref n);
/**//*以字母开头*/
if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_'))
{ ')))
{
array[i++]=ch;
ch = getchc(ref n);
}
array[i++] = '\0';
word = joinString(array,array.Length);
ch_manage(word);
if(n<sourceCode.Length)n--;')
{
/**//*以数字开头*/')
{
array[i++]=ch;
ch = getchc(ref n);
}
array[i++] = '\0';
word=joinString(array,array.Length);
cs_manage(word);
if(n<sourceCode.Length)n--;
}
else if((ch==' ')||(ch=='\t'))
/**//*消除空格符和水平制表符*/
;
else if(ch=='\n')
/**//*消除回车并记录行数*/
line++;
else if(ch=='/')
{
/**//*消除注释*/
ch = getchc(ref n);
if(ch=='=')
{
/**//*判断是否为‘/=’符号*/
this.OutputList.Add(String.Format("/=\t\t\t4\t\t\t32"));
}
else if(ch!='*')
{
/**//*若为除号,写入输出*/
this.OutputList.Add(String.Format("/\t\t\t4\t\t\t13"));
n--;
} else if(ch=='*')
{
/**//*若为注释的开始,消除包含在里面的所有字符*/;
ch = getchc(ref n);)
{
/**//*当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束*/;
while(ch!='*')
ch = getchc(ref n);
count++;
ch = getchc(ref n);
if(ch=='/')
count++;
else
ch = getchc(ref n);
}
}
}
else if(ch=='"')
{
/**//*消除包含在双引号中的字符串常量*/
this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t37",ch));
while(ch!='"')
ch = getchc(ref n);
this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t37",ch));
}
else
{
/**//*首字符为其它字符,即运算限界符或非法字符*/]=ch;

/**//*再读入下一个字符,判断是否为双字符运算、限界符*/
ch = getchc(ref n);
/**//*若该字符非结束符*/
if(n<sourceCode.Length)
{]=ch;
] = '\0';
);
); /**//*先检索是否为双字符运算、限界符*/
)
{
/**//*若不是*/ ] = '\0';
);
);

/**//*检索是否为单字符运算、限界符*/)
{
/**//*若还不是,则为非法字符*/],line);
errorno++;
n--;
}
else
{
/**//*若为单字符运算、限界符,写入输出并将扫描指针回退一个字符*/
this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}\t",word,result));
n--;
}
}
else
{
/**//*若为双字符运算、限界符,写输出*/
this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}",word,result));
}
}
else
{
/**//*若读入的下一个字符为结束符*/] = '\0';
);

/**//*只考虑是否为单字符运算、限界符*/);

/**//*若不是,转出错处理*/)
],line);

else
{
/**//*若是,写输出*/
this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}",word,result));
}
}
}
ch = getchc(ref n);
}
/**//*报告错误字符个数*/
this.OutputList.Add(String.Format("\n共有 {0} 个错误.\n",errorno));
}
}
}
代码可能似曾相识,因为我是参考的一篇C的代码;
这里下载工程源码(带C代码)
2005年4月22日 S.F.
出处:http://www.cnblogs.com/chinasf/archive/2005/04/22/143449.html
C语言词法分析:C#源码的更多相关文章
- [Go语言]从Docker源码学习Go——function和method
function和method关系 method是针对某一类型定义的function, function可以单独调用,method必须针对某一类型的实例进行调用 //function 调用方式 pac ...
- [Go语言]从Docker源码学习Go——指针和Structs
这两天在看reflect这个包在Docker中的使用时,遇到了各种问题,最后虽然知道怎么用了. 但是对于这块的原理还不是太懂,于是把"THE WAY TO GO"中关键的几章看了下 ...
- [Go语言]从Docker源码学习Go——结构和函数的定义
Docker在最近很火,而作为Docker的开发语言-Go也再次被大家提到. 已经使用Docker一段时间了,但是对于源码,尤其是其开发语言Go却一直是一知半解. 最近准备利用空余时间从Docker源 ...
- Markdown 标记语言指北 - 源码
这是上一篇博客的源代码. 这是班刊约稿的一篇文章. 全文约6000字, 预计需要 60 分钟读完. # Markdown 标记语言指北 #### TOC 1. [什么是 Markdown?](#%E4 ...
- 详解Go语言调度循环源码实现
转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/448 本文使用的go的源码15.7 概述 提到"调度&q ...
- Go语言 context包源码学习
你必须非常努力,才能看起来毫不费力! 微信搜索公众号[ 漫漫Coding路 ],一起From Zero To Hero ! 前言 日常 Go 开发中,Context 包是用的最多的一个了,几乎所有函数 ...
- 迪杰斯特拉(dijkstra)算法的简要理解和c语言实现(源码)
迪杰斯特拉(dijkstra)算法:求最短路径的算法,数据结构课程中学习的内容. 1 . 理解 算法思想::设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合 ...
- C语言学生管理系统源码分享
大家好 我就是如假包换的...陈玲 自从运营了C语言程序设计微信公众号 很多粉丝都给我备注 ...奇葩 实在是不敢当 也被人开始叫玲玲姐 我知道 很多人都想看我出境 我本人也有 年多的舞台演讲训练 实 ...
- [Go语言]从Docker源码学习Go——init()方法和identifier首字母大小写区分
init()方法 如果想在一个go文件里,进行一些初始化的工作,可以把代码放到init()方法中. init()方法先被执行. func init() { // initialization of p ...
随机推荐
- 20145219 《Java程序设计》第06周学习总结
20145219 <Java程序设计>第06周学习总结 教材学习内容总结 InputStream与OutputStream 串流设计 1.串流:Java将输入/输出抽象化为串流,数据有来源 ...
- 简单介绍java Enumeration(转)
Enumeration接口 Enumeration接口本身不是一个数据结构.但是,对其他数据结构非常重要. Enumeration接口定义了从一个数据结构得到连续数据的手段.例如,Enumeratio ...
- 搭建 Spring 开发环境
把以下 jar 包加入到工程的 classpath 下: Spring 的配置文件: 一个典型的 Spring 项目需要创建一个或多个 Bean 配置文件, 这些配置文件用于在 Spring IOC ...
- 并发-AQS源码分析
AQS源码分析 参考: http://www.cnblogs.com/waterystone/p/4920797.html https://blog.csdn.net/fjse51/article/d ...
- CocoaPods学习系列4——进阶用法
这篇文章,记录一下CocoaPods的进阶用法. 进阶用法主要体现在.podspec文件和Podfile的配置上. .podspec文件的进阶配置 以官方的一个.podspec文件示例细说: Pod: ...
- Android -- 利用ContentProvider 读取和写入短信
1. 读写短信 示例代码 均需要先获得读写短信的权限 <uses-permission android:name="android.permission.WRITE_SMS" ...
- 云服务器用ssh登录
本地生成密钥 这里选择在购买前先在本地生成密钥key(分为private key和public key),所以先生成密钥再进行购买,购买完以后直接ssh登录,不需要输入密码(安全性考虑) 其中,pub ...
- java 在Excel中插入图片 POI实现
一.POI简介 Jakarta POI 是apache的子项目,目标是处理ole2对象.它提供了一组操纵Windows文档的Java API 目前比较成熟的是HSSF接口,处理MS Excel(97- ...
- 20165332 预备作业三 Linux安装及命令入门
Linux安装及命令入门 一.安装Linux操作系统 由于做的比较晚,结合大多数同学的经验和娄老师的<基于VirtualBox虚拟机安装Ubuntu图文教程>,整个安装过程还算顺利,唯一遇 ...
- lightoj1370欧拉函数/素数筛
这题有两种解法,1是根据欧拉函数性质:素数的欧拉函数值=素数-1(可根据欧拉定义看出)欧拉函数定义:小于x且与x互质的数的个数 #include<map> #include<set& ...