c语言词法分析:C#源码

简介:

今天继续研究代码解析的算法
这个是算法流程图

有图解可能更直观一点;
以下是c#源码:

1 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();
67 for(int i=1;i<key.Length;i++)
68 this.KeyWordList.Add(key[i]);
69
70 this.LimitList.Clear();
71 this.LimitList.TrimToSize();
72 for(int i=1;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){
89 int[] temp= new int[20];
90 string binary = "";
91 int val=0,i=0;
92
93 /*先将字符转化为十进制数*/
94 try{
95 val = Convert.ToInt32(buf);
96 }
catch{
97 val = 0;
98 }

99
100 if(val==0) {
101 return(val.ToString());
102 }

103
104 i=0;
105 while(val!=0) {
106 temp[i++]=val%2;
107 val/=2;
108 }

109
110 binary = "";
111 for(int j=0;j<=i-1;j++)
112 binary += (char)(temp[i-j-1]+48);
113
114 return(binary);
115 }

116
117 /*******************************************
118 * 根据不同命令查表或造表函数
119 *******************************************/

120 private int find(string buf,int type,int command){
121 int number=0;
122 string temp;
123
124 IEnumerator ie = null;
125 ArrayList al = null;
126 switch(type){
127 case 1://关键字表
128 ie = this.KeyWordList.GetEnumerator();
129 break;
130 case 2://标识符表
131 ie = this.IdentifierList.GetEnumerator();
132 break;
133 case 3://常数表
134 ie = this.ConstList.GetEnumerator();
135 break;
136 case 4://运算、限界符表
137 ie = this.LimitList.GetEnumerator();
138 break;
139 }

140
141 if(ie!=null)
142 while (ie.MoveNext()){
143 temp = ie.Current.ToString();
144 if(temp.Trim().ToLower()==buf.Trim().ToLower()){
145 return number;
146 }

147 number ++;
148 }

149
150 if(command==1){
151 /*找不到,当只需查表,返回0,否则还需造表*/
152 return 0;
153 }

154
155 switch(type){
156 case 1: al = this.KeyWordList;break;
157 case 2: al = this.IdentifierList;break;
158 case 3: al = this.ConstList;break;
159 case 4: al = this.LimitList;break;
160 }

161 if(al!=null)
162 al.Add(buf);
163
164 return number + 1;
165 }

166 /*******************************************
167 * 数字串处理函数
168 *******************************************/

169 private void cs_manage(string buffer){
170 string binary = dtb(buffer);
171 int result = find(binary,3,2);
172 this.OutputList.Add(String.Format("{0}\t\t\t3\t\t\t{1}",buffer,result));
173 }

174
175 /*******************************************
176 * 字符串处理函数
177 *******************************************/

178 private void ch_manage(string buffer) {
179 int result = find(buffer,1,1);
180 if(result!=0){
181 this.OutputList.Add(String.Format("{0}\t\t\t1\t\t\t{1}",buffer,result));
182 }
else{
183 result = find(buffer,2,2);
184 this.OutputList.Add(String.Format("{0}\t\t\t2\t\t\t{1}",buffer,result));
185 }

186 }

187
188 /*******************************************
189 * 出错处理函数
190 *******************************************/

191 private void er_manage(char error,int lineno) {
192 this.OutputList.Add(String.Format("错误关键字: {0} ,所在行: {1}",error,lineno));
193 }

194
195 /*******************************************
196 * 转换Char数组为string
197 ******************************************/

198 private string joinString(char[] array,int Length){
199 string s = "";
200 if(array.Length>0)
201 for(int i=0;i<Length;i++){
202 if(array[i]!='\0') {
203 s+=array[i];
204 }
else{
205 break;
206 }

207 }

208 return s;
209 }

210
211 private char getchc(ref int n){
212 char[] c = sourceCode.ToCharArray();
213 if(n<c.Length){
214 char r = c[n];
215 n++;
216 return r;
217 }

218 return sourceCode[sourceCode.Length-1];
219 }

220 /*******************************************
221 * 扫描程序
222 ********************************************/

223 public void Parse() {
224 //StreamWriter fpout = null;
225 char ch ;
226 int i=0,line=1;
227 int count,result,errorno=0;
228 char[] array = new char[30];
229 string word= "";
230
231 /*按字符依次扫描源程序,直至结束*/
232 int n = 0;
233
234 while(n<sourceCode.Length-1){
235 i = 0;
236 ch = getchc(ref n);
237 /*以字母开头*/
238 if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')) {
239 while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')||((ch>='0')&&(ch<='9'))) {
240 array[i++]=ch;
241 ch = getchc(ref n);
242 }

243 array[i++] = '\0';
244 word = joinString(array,array.Length);
245 ch_manage(word);
246 if(n<sourceCode.Length)n--;
247 }
else if(ch>='0'&&ch<='9') {
248 /*以数字开头*/
249 while(ch>='0'&&ch<='9') {
250 array[i++]=ch;
251 ch = getchc(ref n);
252 }

253 array[i++] = '\0';
254 word=joinString(array,array.Length);
255 cs_manage(word);
256 if(n<sourceCode.Length)n--;
257 }

258 else if((ch==' ')||(ch=='\t'))
259 /*消除空格符和水平制表符*/
260 ;
261 else if(ch=='\n')
262 /*消除回车并记录行数*/
263 line++;
264 else if(ch=='/') {
265 /*消除注释*/
266 ch = getchc(ref n);
267 if(ch=='=') {
268 /*判断是否为‘/=’符号*/
269 this.OutputList.Add(String.Format("/=\t\t\t4\t\t\t32"));
270 }

271 else if(ch!='*') {
272 /*若为除号,写入输出*/
273 this.OutputList.Add(String.Format("/\t\t\t4\t\t\t13"));
274 n--;
275 }
else if(ch=='*') {
276 /*若为注释的开始,消除包含在里面的所有字符*/
277 count=0;
278 ch = getchc(ref n);
279 while(count!=2) {
280 /*当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束*/
281 count=0;
282 while(ch!='*')
283 ch = getchc(ref n);
284 count++;
285 ch = getchc(ref n);
286 if(ch=='/')
287 count++;
288 else
289 ch = getchc(ref n);
290 }

291 }

292 }

293 else if(ch=='"') {
294 /*消除包含在双引号中的字符串常量*/
295 this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t37",ch));
296 while(ch!='"')
297 ch = getchc(ref n);
298 this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t37",ch));
299 }

300 else {
301 /*首字符为其它字符,即运算限界符或非法字符*/
302 array[0]=ch;
303 /*再读入下一个字符,判断是否为双字符运算、限界符*/
304 ch = getchc(ref n);
305 /*若该字符非结束符*/
306 if(n<sourceCode.Length) {
307 array[1]=ch;
308 array[2] = '\0';
309 word = joinString(array,2);
310 result=find(word,4,1); /*先检索是否为双字符运算、限界符*/
311 if(result==0) {
312 /*若不是*/
313 array[2] = '\0';
314 word = joinString(array,1);
315 result=find(word,4,1);
316 /*检索是否为单字符运算、限界符*/
317 if(result==0) {
318 /*若还不是,则为非法字符*/
319 er_manage(array[0],line);
320 errorno++;
321 n--;
322 }

323 else {
324 /*若为单字符运算、限界符,写入输出并将扫描指针回退一个字符*/
325 this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}\t",word,result));
326 n--;
327 }

328 }

329 else {
330 /*若为双字符运算、限界符,写输出*/
331 this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}",word,result));
332 }

333 }

334 else {
335 /*若读入的下一个字符为结束符*/
336 array[2] = '\0';
337 word = joinString(array,1);
338 /*只考虑是否为单字符运算、限界符*/
339 result=find(word,4,1);
340 /*若不是,转出错处理*/
341 if(result==0)
342 er_manage(array[0],line);
343 else {
344 /*若是,写输出*/
345 this.OutputList.Add(String.Format("{0}\t\t\t4\t\t\t{1}",word,result));
346 }

347 }

348 }

349 ch = getchc(ref n);
350 }

351 /*报告错误字符个数*/
352 this.OutputList.Add(String.Format("\n共有 {0} 个错误.\n",errorno));
353 }

354
355 }

356}




本文转自suifei博客园博客,原文链接:http://www.cnblogs.com/Chinasf/archive/2005/04/22/143449.html,如需转载请自行联系原作者
相关文章
|
3月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
328 9
|
4月前
|
存储 C语言
【C语言篇】深入理解指针3(附转移表源码)
【C语言篇】深入理解指针3(附转移表源码)
58 1
|
3月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
149 16
|
3月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
192 7
|
3月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(上)(c语言实现)(附源码)
本文介绍了四种常见的排序算法:冒泡排序、选择排序、插入排序和希尔排序。通过具体的代码实现和测试数据,详细解释了每种算法的工作原理和性能特点。冒泡排序通过不断交换相邻元素来排序,选择排序通过选择最小元素进行交换,插入排序通过逐步插入元素到已排序部分,而希尔排序则是插入排序的改进版,通过预排序使数据更接近有序,从而提高效率。文章最后总结了这四种算法的空间和时间复杂度,以及它们的稳定性。
153 8
|
3月前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
209 8
|
3月前
|
C语言 Windows
C语言课设项目之2048游戏源码
C语言课设项目之2048游戏源码,可作为课程设计项目参考,代码有详细的注释,另外编译可运行文件也已经打包,windows电脑双击即可运行效果
53 1
|
3月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
163 4
|
3月前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
110 3
|
4月前
|
存储 API C语言
【C语言】实践:贪吃蛇小游戏(附源码)(一)
【C语言】实践:贪吃蛇小游戏(附源码)

热门文章

最新文章