今天繼續研究代碼解析的算法
這個是算法流程圖
html
有圖解可能更直觀一點;
如下是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
}
357
代碼可能似曾相識,由於我是參考的一篇C的代碼;
這裏下載工程源碼(帶C代碼)
2005年4月22日 S.F.
c#