自己动手设计代码编辑器——(五)分析源代码

因为之前的设计不合理,就重新开了工程。花了几天时间,重做的进度赶上之前的了
今天来说说分析源代码
源码分析中会用到的其它东西,之前都介绍过了。
接下来看UParser这个类中最后的函数GetNextCut,是用来把源码分析为UCodeCut集合的。其中包括关键字设别,变量设别等等

开始

    UCodeCut cut = new UCodeCut();  
    List<byte> cutData = new List<byte>();  
    byte b;  
    UCutType currType = UCutType.None; // 状态机的状态  
      
    bool inString = false; // 是否解析字符串  
      
    if (EndOfCode == true)  
    {  
    cut.CutType = UCutType.End;  
    return cut;  
    }  

开头就是定义一些变量,并且判断分析是否结束
cut用于保存分析玩的CodeCut
cutData是cut中的具体数据
currType是当前状态机的状态

接下来是状态机的循环

while (!EndOfCode)  
{  
b = GetNextByte();  
cutData.Add(b);  
...  
...  
} 

然后是状态机的入口

    #region UCutType.None  
                        if (currType == UCutType.None)  
                        {  
                            if (b == UConfig.Space)  
                            {  
                                currType = UCutType.Space;  
                                continue;  
                            }  
      
                            if (b == UConfig.Tab)  
                            {  
                                currType = UCutType.Tab;  
                                break;  
                            }  
      
                            if (b == UConfig.DoubleQuote)  
                            {  
                                currType = UCutType.String;  
                                inString = true;  
                                continue;  
                            }  
      
                            if (b == UConfig.NewLine)  
                            {  
                                currType = UCutType.NewLine;  
      
                                // 跳过回车符  
                                if (PeekNextByte() == UConfig.Enter)  
                                {  
                                    GetNextByte();  
                                }  
      
                                break;  
                            }  
      
                            if (b == UConfig.BackSlash)  
                            {  
                                if (PeekNextByte() == UConfig.BackSlash)  
                                {  
                                    currType = UCutType.Annotation;  
                                    continue;  
                                }  
                            }  
      
                            if (UHelper.IsSymbol(b))  
                            {  
                                currType = UCutType.Symbol;  
                                break;  
                            }  
      
                            if (UHelper.IsCharacter(b))  
                            {  
                                currType = UCutType.Normal;  
                                continue;  
                            }  
      
                            if (UHelper.IsDigit(b))  
                            {  
                                currType = UCutType.Digit;  
                                continue;  
                            }  
                        }  
                        #endregion  

接下来是Normal状态,就是一些普通的字符串

    #region UCutType.Normal  
                        if (currType == UCutType.Normal)  
                        {  
                            if (UHelper.IsCutEnd(b))  
                            {  
                                BackToLastByte();  
      
                                cutData.RemoveAt(cutData.Count - 1);  
                                break;  
                            }  
                        }  
                        #endregion  

接下来是String状态,是字符串

#region UCutType.String  
                    if (currType == UCutType.String)  
                    {  
                        if (b == UConfig.NewLine)  
                        {  
                            BackToLastByte();  
  
                            currType = UCutType.Normal;  
                            break;  
                        }  
  
                        if (b == UConfig.DoubleQuote)  
                        {  
                            inString = false;  
                            break;  
                        }  
  
                        if (b == UConfig.Slash)  
                        {  
                            // 添加 \ 后的字符  
                            if (inString)  
                            {  
                                //ch = (char)GetNextChar();  
                                //cutData.Add((byte)ch);  
                                cutData.Add(GetNextByte());  
                                continue;  
                            }  
                        }  
                    }  
                    #endregion

接下来 数字状态、注释等等,都一样的判断格式
最后循环结束,检查关键字

    // 替换Tab为Space  
                    if (currType == UCutType.Tab)  
                    {  
                        cut.Data = UConfig.TabString;  
                        cut.CutType = UCutType.Space;  
                    }  
                    else  
                    {  
                        cut.Data = UHelper.GetStringByBytes(cutData.ToArray());  
                        cut.CutType = currType;  
                          
                        // 如果是普通的一段文本,判断是否为关键字  
                        if (currType == UCutType.Normal)  
                        {  
                            if (UHelper.IsKeyWord(cut.Data))  
                            {  
                                cut.CutType = UCutType.KeyWord;  
                            }  
                        }  
                    }  

最后检查,是否为变量或者类

if (currType == UCutType.Normal)  
                {  
                    if (LastCut2.CutType == UCutType.KeyWord && LastCut1.CutType == UCutType.Space)  
                    {  
                        // 类的定义  
                        if (LastCut2.Data == UConfig.ClassString)  
                        {  
                            cut.CutType = UCutType.ClassName;  
                        }  
                        else  
                        {  
                            // 函数名的定义  
                            foreach (string str in UConfig.FunctionDefineString)  
                            {  
                                if (str == LastCut2.Data)  
                                {  
                                    if (PeekNextByte() == (byte)'(')  
                                    {  
                                        cut.CutType = UCutType.FunctionName;  
                                    }  
                                    else  
                                    {  
                                        cut.CutType = UCutType.VariableName;  
                                    }  
                                    break;  
                                }  
                            }  
                        }  
                    }  
                }  
  
                LastCut2 = LastCut1;  
                LastCut1 = cut; 

这就是一个CodeCut的分析过程了
接下来只要不断的调用GetNextCut()就能分析完整个代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,387评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,845评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,091评论 0 246
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,308评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,662评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,795评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,008评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,743评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,466评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,687评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,181评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,531评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,177评论 3 239
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,126评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,862评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,734评论 2 274

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,581评论 25 707
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • 戴旺 昨天有幸学习了两位李老师的语文课,让我对语文教学有了新的认识。 ...
    戴言旺语阅读 215评论 0 1
  • 今天给自己打70分,上午听了任红霞十九大宣讲报告,下午开了会,宣布了任命,可我一点感觉都没有,换做几年前或许会高兴...
    小熊熊1234阅读 148评论 0 0