美文网首页
自己动手设计代码编辑器——(五)分析源代码

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

作者: UnSkyToo | 来源:发表于2017-09-19 11:26 被阅读0次

    因为之前的设计不合理,就重新开了工程。花了几天时间,重做的进度赶上之前的了
    今天来说说分析源代码
    源码分析中会用到的其它东西,之前都介绍过了。
    接下来看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()就能分析完整个代码

    相关文章

      网友评论

          本文标题:自己动手设计代码编辑器——(五)分析源代码

          本文链接:https://www.haomeiwen.com/subject/xpdwsxtx.html