首页 > 代码库 > C语言词法分析:C#源码

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技术分享}

357技术分享

 

 

代码可能似曾相识,因为我是参考的一篇C的代码;

这里下载工程源码(带C代码) 
2005年4月22日 S.F.

 

出处:http://www.cnblogs.com/chinasf/archive/2005/04/22/143449.html

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