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