今天继续研究代码解析的算法
这个是算法流程图
有图解可能更直观一点;
以下是c#源码:
1using System;
2using System.IO;
3using System.Text;
4using System.Windows.Forms;
5using System.Collections;
6
7namespace 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));
}
}
}
2using System.IO;
3using System.Text;
4using System.Windows.Forms;
5using System.Collections;
6
7namespace 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