C語言詞法分析:C#源碼

今天繼續研究代碼解析的算法
這個是算法流程圖
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#

 

出處:http://www.cnblogs.com/chinasf/archive/2005/04/22/143449.html數組

相關文章
相關標籤/搜索