因?yàn)橹暗脑O(shè)計不合理,就重新開了工程?;藥滋鞎r間,重做的進(jìn)度趕上之前的了
今天來說說分析源代碼
源碼分析中會用到的其它東西,之前都介紹過了。
接下來看UParser這個類中最后的函數(shù)GetNextCut,是用來把源碼分析為UCodeCut集合的。其中包括關(guān)鍵字設(shè)別,變量設(shè)別等等
開始
UCodeCut cut = new UCodeCut();
List<byte> cutData = new List<byte>();
byte b;
UCutType currType = UCutType.None; // 狀態(tài)機(jī)的狀態(tài)
bool inString = false; // 是否解析字符串
if (EndOfCode == true)
{
cut.CutType = UCutType.End;
return cut;
}
開頭就是定義一些變量,并且判斷分析是否結(jié)束
cut用于保存分析玩的CodeCut
cutData是cut中的具體數(shù)據(jù)
currType是當(dāng)前狀態(tài)機(jī)的狀態(tài)
接下來是狀態(tài)機(jī)的循環(huán)
while (!EndOfCode)
{
b = GetNextByte();
cutData.Add(b);
...
...
}
然后是狀態(tài)機(jī)的入口
#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狀態(tài),就是一些普通的字符串
#region UCutType.Normal
if (currType == UCutType.Normal)
{
if (UHelper.IsCutEnd(b))
{
BackToLastByte();
cutData.RemoveAt(cutData.Count - 1);
break;
}
}
#endregion
接下來是String狀態(tài),是字符串
#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
接下來 數(shù)字狀態(tài)、注釋等等,都一樣的判斷格式
最后循環(huán)結(jié)束,檢查關(guān)鍵字
// 替換Tab為Space
if (currType == UCutType.Tab)
{
cut.Data = UConfig.TabString;
cut.CutType = UCutType.Space;
}
else
{
cut.Data = UHelper.GetStringByBytes(cutData.ToArray());
cut.CutType = currType;
// 如果是普通的一段文本,判斷是否為關(guān)鍵字
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
{
// 函數(shù)名的定義
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的分析過程了
接下來只要不斷的調(diào)用GetNextCut()就能分析完整個代碼