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

有图解可能更直观一点;

以下是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));

    }



  }

}

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

这里下载工程源码(带C代码) 

2005年4月22日 S.F.

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

C语言词法分析:C#源码的更多相关文章

  1. [Go语言]从Docker源码学习Go——function和method

    function和method关系 method是针对某一类型定义的function, function可以单独调用,method必须针对某一类型的实例进行调用 //function 调用方式 pac ...

  2. [Go语言]从Docker源码学习Go——指针和Structs

    这两天在看reflect这个包在Docker中的使用时,遇到了各种问题,最后虽然知道怎么用了. 但是对于这块的原理还不是太懂,于是把"THE WAY TO GO"中关键的几章看了下 ...

  3. [Go语言]从Docker源码学习Go——结构和函数的定义

    Docker在最近很火,而作为Docker的开发语言-Go也再次被大家提到. 已经使用Docker一段时间了,但是对于源码,尤其是其开发语言Go却一直是一知半解. 最近准备利用空余时间从Docker源 ...

  4. Markdown 标记语言指北 - 源码

    这是上一篇博客的源代码. 这是班刊约稿的一篇文章. 全文约6000字, 预计需要 60 分钟读完. # Markdown 标记语言指北 #### TOC 1. [什么是 Markdown?](#%E4 ...

  5. 详解Go语言调度循环源码实现

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/448 本文使用的go的源码15.7 概述 提到"调度&q ...

  6. Go语言 context包源码学习

    你必须非常努力,才能看起来毫不费力! 微信搜索公众号[ 漫漫Coding路 ],一起From Zero To Hero ! 前言 日常 Go 开发中,Context 包是用的最多的一个了,几乎所有函数 ...

  7. 迪杰斯特拉(dijkstra)算法的简要理解和c语言实现(源码)

    迪杰斯特拉(dijkstra)算法:求最短路径的算法,数据结构课程中学习的内容. 1 . 理解 算法思想::设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合 ...

  8. C语言学生管理系统源码分享

    大家好 我就是如假包换的...陈玲 自从运营了C语言程序设计微信公众号 很多粉丝都给我备注 ...奇葩 实在是不敢当 也被人开始叫玲玲姐 我知道 很多人都想看我出境 我本人也有 年多的舞台演讲训练 实 ...

  9. [Go语言]从Docker源码学习Go——init()方法和identifier首字母大小写区分

    init()方法 如果想在一个go文件里,进行一些初始化的工作,可以把代码放到init()方法中. init()方法先被执行. func init() { // initialization of p ...

随机推荐

  1. PHP面向对象程序设计之抽象类和抽象方法

    抽象类: 抽象类不能被实例化.抽象类中只定义(或部分实现)子类需要的方法.子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化. 我们可以用一个abstract关键字来定义一个抽象类,示例如下: ...

  2. eclipse——反编译插件

    百度云链接 链接:https://pan.baidu.com/s/1iEtstiK5mJ4kDp6gTfVBww 密码:8wf7 在线安装地址 http://jd.benow.ca/jd-eclips ...

  3. JMS-activeMq点对点模式

    上一篇对JMS进行介绍了一下,接下来总结一下activemq点对点模式以及订阅发布模式. (1)下载:首先到官网http://activemq.apache.org下载activemq (2)运行:解 ...

  4. Hibernate -- 项目结构模型改造, 加 Utils 和 Dao层

    示例代码: App.java 模拟客户端 /** * 模拟客户端 */ public class App { @Test public void saveCustomer(){ CustomerDao ...

  5. Source Insight 插件

    一提到外挂程序,大家肯定都不陌生,QQ就有很多个版本的去广告外挂,很多游戏也有用于扩展功能或者作弊的工具,其中很多也是以外挂的形式提供的.外挂和插件的区别在于插件通常依赖于程序的支持,如果程序不支持插 ...

  6. sklearn学习笔记之开始

    简介   自2007年发布以来,scikit-learn已经成为Python重要的机器学习库了.scikit-learn简称sklearn,支持包括分类.回归.降维和聚类四大机器学习算法.还包含了特征 ...

  7. 使用springmvc时报错org.springframework.beans.NullValueInNestedPathException: Invalid property 'department' of bean class [com.atguigu.springmvc.crud.entities.Employee]:

    使用springmvc时报错 org.springframework.beans.NullValueInNestedPathException: Invalid property 'departmen ...

  8. vmware增加共享文件夹

    增加共享文件夹 VMWare提供共享文件夹功能.前提是在虚拟机中安装VMware tools 1. 安装VMware tools 会自动在虚拟机中的/media/VMware Tools/中有个压缩包 ...

  9. kindeditor上传本地图片实例

    所需插件:kindeditor下载   密码: 5ry4 jsp文件: <script type="text/javascript" language="javas ...

  10. Ajax-07 基于Ajax实现跨域请求

    跨域 跨域名访问,如c1.com域名向c2.com域名发送请求 本质:浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. django服务端准备 url. ...