/// <summary> /// 设置值语句块的分析 /// </summary> /// <param name="parent"></param> private void SetValueBlockAnalyze(AnalyzeBlock parent) { var vard = parent.Elements[0]; var varv = parent.Elements.Count < 3 ? null : parent.Elements[2]; if (vard.Word != ",") { SetVarDataType(vard as WordUnit, varv); return; } var blocka = vard as AnalyzeBlock; if (blocka == null || blocka.Elements.Count == 0) { return; } var blockb = varv as AnalyzeBlock; if (blockb == null) { SetVarDataType(blocka.Elements[0] as WordUnit, varv); for (var i = 1; i < blocka.Elements.Count; i++) { SetVarDataType(blocka.Elements[i] as WordUnit, null); } } else { for (var i = 1; i < blocka.Elements.Count; i++) { SetVarDataType(blocka.Elements[i] as WordUnit, i >= blockb.Elements.Count ? null : blockb.Elements[i]); } } }
/// <summary> /// In关键字的类型确定 /// </summary> /// <param name="block"></param> private void CheckInType(AnalyzeBlock block) { if (block.Elements.Count > 2) { block.Elements[0].ValueType = block.Elements[block.Elements.Count - 1].ValueType ?? LuaDataTypeItem.Nil; } else { block.Elements[0].ValueType = LuaDataTypeItem.Nil; } if (block.Elements[0].ItemType == CodeItemType.Separator_Comma) { SetMulitType(block.Elements[0] as AnalyzeBlock); return; } if (_vers.ContainsKey(block.Elements[0].Name)) { _vers[block.Elements[0].Name] = block.Elements[0].ValueType; } else { _vers.Add(block.Elements[0].Name, block.Elements[0].ValueType); } }
private void ConnectBlock(AnalyzeBlock root) { for (int level = 1; level < 4; level++) { ConnectBlock(root, level); } }
/// <summary> /// In关键字的类型确定 /// </summary> /// <param name="block"></param> private void SetMulitType(AnalyzeBlock block) { if (block == null || block.ItemType != CodeItemType.Separator_Comma || block.ValueType == null || block.ValueType.ValueType != LuaDataType.Mulit) { return; } int idx = 0; foreach (var word in block.Elements.OfType <WordUnit>()) { if (idx >= block.ValueType.Childs.Count || word.IsKeyWord || word.ItemType == CodeItemType.Separator_Comma) { continue; } word.ValueType = block.ValueType.Childs[idx++]; if (_vers.ContainsKey(word.Word)) { _vers[word.Word] = word.ValueType; } else { _vers.Add(word.Word, word.ValueType); } } }
public void ClearEmpty(AnalyzeBlock root) { foreach (var unit in root.ResetElements()) { if (unit.IsEmpty) { continue; } var block = unit as AnalyzeBlock; if (block != null) { block.Parent = root; ClearEmpty(block); if (block.Elements.Count == 0) { continue; } block.Release(); root.Append(block.Elements.Count == 1 ? block.Elements[0] : unit); } else { root.Append(unit); } } }
public string PrintTree(AnalyzeBlock root) { var builder = new StringBuilder(); PrintTree(root, builder, 0); return(builder.ToString()); }
/// <summary> /// 类型推导 /// </summary> /// <param name="parent"></param> private void BlockAnalyze(AnalyzeBlock parent) { foreach (var block in parent.Elements.OfType <AnalyzeBlock>()) { if (block.IsEmpty || block.ItemRace == CodeItemRace.Assist || block.ItemFamily == CodeItemFamily.Constant) { continue; } BlockAnalyze(block); switch (block.ItemFamily) { case CodeItemFamily.SetValue: SetValueBlockAnalyze(block); continue; case CodeItemFamily.ValueSentence: switch (block.ItemType) { case CodeItemType.Table_Child: AnalyzeTableChild(block); break; case CodeItemType.Call: AnalyzeCallBlock(block); break; } break; } } }
/// <summary> /// 设置值语句块的分析 /// </summary> /// <param name="parent"></param> private void ComputeBlockAnalyze(AnalyzeBlock parent) { foreach (var ch in parent.Elements) { ch.ValueType = LuaDataTypeItem.NumberValue; AddVariableToDictionary(ch); } }
/// <summary> /// 设置结果值 /// </summary> /// <param name="parent"></param> private void TypeSet(AnalyzeBlock parent) { for (var index = parent.Elements.Count - 1; index >= 0; index--) { var unit = parent.Elements[index]; if (unit.IsEmpty) { continue; } if (unit.ValueType != null && unit.ValueType.ValueType != LuaDataType.Confirm) { continue; } var block = unit as AnalyzeBlock; if (block != null) { TypeSet(block); } if (unit.ItemFamily == CodeItemFamily.ValueSentence && unit.ItemType == CodeItemType.Table_Child) { if (!_vers.ContainsKey(unit.Name)) { _vers.Add(unit.Name, LuaDataTypeItem.Confirm); } continue; } if (unit.ItemType == CodeItemType.String) { unit.ValueType = LuaDataTypeItem.StringValue; continue; } if (unit.ItemType == CodeItemType.Number) { unit.ValueType = LuaDataTypeItem.NumberValue; continue; } if (unit.ItemFamily != CodeItemFamily.Variable) { continue; } var word = unit as WordUnit; if (word == null || word.IsPunctuate) { continue; } LuaDataTypeItem type; if (_vers.TryGetValue(word.Name, out type)) { word.ValueType = type; } else { _vers.Add(word.Name, LuaDataTypeItem.Error); } } }
private void MergeSimpleBlock(AnalyzeBlock root) { int level = 1; for (; level < 10; level++) { MergeSimpleBlock(root, level); } }
private static void LinkBarket(AnalyzeBlock root) { AnalyzeUnitBase pre = null; AnalyzeBlock cur = null; // CodeItemType pretype = CodeItemType.None; foreach (var unit in root.ResetElements()) { var block = unit as AnalyzeBlock; if (block == null) { var word = (WordUnit)unit; pre = word.IsPunctuate || word.IsKeyWord ? null : unit; root.Append(unit); //pretype = CodeItemType.None; continue; } LinkBarket(block); switch (block.ItemType) { case CodeItemType.Brackets21: //case CodeItemType.Brackets31: //if (pretype == CodeItemType.None || cur == null) { if (pre == null) { root.Append(unit); break; } if (pre != cur) { cur?.Release(); cur = new AnalyzeBlock(); var wd = pre as WordUnit; cur.Primary = wd ?? ((AnalyzeBlock)pre).Primary; root.Elements.Remove(pre); cur.Elements.Add(pre); cur.ItemRace = CodeItemRace.Value; cur.ItemFamily = CodeItemFamily.ValueSentence; cur.ItemType = CodeItemType.Brackets21 == block.ItemType ? CodeItemType.Call : CodeItemType.Table_Child; root.Elements.Add(cur); pre = cur; } unit.Name = "_call_"; cur.Elements.Add(unit); } //root.Elements.Add(block); //pretype = block.ItemType; continue; } root.Append(unit); pre = unit; } cur?.Release(); }
/// <summary> /// 区域组合 /// </summary> /// <returns></returns> public void MergeRange(AnalyzeBlock root, int level) { var cur = root; Stack <AnalyzeBlock> stack = new Stack <AnalyzeBlock>(); foreach (var u in root.ResetElements()) { if (u.IsEmpty) { continue; } var unit = u; var child = unit as AnalyzeBlock; if (child != null) { if (!unit.IsLock && !unit.IsUnit) { MergeRange((AnalyzeBlock)unit, level); } cur.Append(unit); continue; } var word = unit as WordUnit; if (unit.JoinLevel == level) { switch (unit.JoinFeature) { case JoinFeature.RangeOpen: stack.Push(cur); var block = new AnalyzeBlock { Parent = cur, Primary = word }; cur.Append(block); cur.JoinFeature = JoinFeature.BeforeBy; cur = block; break; case JoinFeature.RangeClose: cur.Append(unit); if (stack.Count == 0) { cur.IsError = true; cur = root; } else { cur = stack.Pop(); } continue; } } cur.Append(unit); } }
/// <summary> /// 类型推导 /// </summary> public static void Analyze(AnalyzeBlock root, TemplateConfig config) { var analyzer = new LuaTypeAnalyzer { Root = root, Config = config }; analyzer.DoAnalyze(); }
/// <summary> /// 分析方法调用块(不在子级连接中) /// </summary> /// <param name="block"></param> private void AnalyzeCallBlock(AnalyzeBlock block) { if (block.Parent.ItemType == CodeItemType.Table_Child) { return; } LuaDataTypeItem type; var name = block.Name ?? block.Word; if (_vers.TryGetValue(name, out type)) { block.IsError = false; block.ValueType = type; return; } var cn = block.Elements[0].Word; if (!_vers.TryGetValue(cn, out type)) { block.IsError = true; block.ValueType = LuaDataTypeItem.Error; block.Elements[0].ValueType = LuaDataTypeItem.Confirm; return; } block.Elements[0].ValueType = type; block.Elements[1].ValueType = type; var error = false; for (var index = 2; index < block.Elements.Count; index++) { if (error) { block.Elements[index].IsError = true; } else if (type.ValueType != LuaDataType.Function || !_vers.TryGetValue(type.Name, out type)) { error = true; block.Elements[index].IsError = true; block.ValueType = LuaDataTypeItem.Error; } else { block.Elements[index].ValueType = type; } } if (error) { block.IsError = true; block.ValueType = LuaDataTypeItem.Error; return; } _vers.Add(name, type); block.IsError = false; block.ValueType = type; }
private void CheckTableItem(AnalyzeBlock parent, AnalyzeUnitBase element, int idx) { string name; switch (element.ItemType) { case CodeItemType.Brackets31: name = element.Name ?? element.Word; element.ValueType = LuaDataTypeItem.Nil; break; case CodeItemType.Separator_Equal: var block = (AnalyzeBlock)element; if (block.Elements.Count <= 1) { name = $"[{idx}]"; element.ValueType = LuaDataTypeItem.Nil; } else { var ne = block.Elements[0]; name = ne.Name ?? ne.Word; if (ne.ItemType != CodeItemType.Brackets31) { name = $"['{name}']"; } if (block.Elements.Count > 2) { block.ValueType = ne.ValueType = block.Elements[2].ValueType; } else { ne.ValueType = LuaDataTypeItem.Nil; } } break; default: name = $"[{idx}]"; if (element.ValueType == null) { element.ValueType = LuaDataTypeItem.Nil; } break; } if (element.ValueType == null) { element.ValueType = LuaDataTypeItem.Nil; } _vers.Add($"{parent.Name}{name}", element.ValueType); }
/// <summary> /// 设置值语句块的分析 /// </summary> /// <param name="parent"></param> private void SetValueBlockAnalyze(AnalyzeBlock parent) { if (parent.Elements.Count == 0) { return; } var def = parent.Elements[0]; var block = def as AnalyzeBlock; if (block != null && block.ItemType == CodeItemType.Key_Local) { def = block.Elements[1]; } SetVarDataType(def, parent.Elements.Count < 3 ? null : parent.Elements[2]); }
public void Release(AnalyzeBlock root) { foreach (var unit in root.Elements) { if (unit.IsEmpty) { continue; } if (root.IsError) { unit.IsError = true; } var block = unit as AnalyzeBlock; if (block != null) { Release(block); } } }
/// <summary> /// 连接类型分析 /// </summary> /// <param name="parent"></param> private void TypeLink(AnalyzeBlock parent) { foreach (var unit in parent.Elements) { if (unit.IsEmpty) { continue; } var block = unit as AnalyzeBlock; if (block != null) { TypeLink(block); } if (unit.ValueLink != null) { unit.ValueType = unit.ValueLink.ValueType; } } }
/// <summary> /// 分析方法调用块(在子级连接中) /// </summary> /// <param name="block"></param> /// <param name="type"></param> private bool AnalyzeCallBlock(AnalyzeBlock block, out LuaDataTypeItem type) { var error = false; var i = 0; if (_vers.TryGetValue(block.Elements[i].Word, out type)) { block.Elements[0].ValueType = type; block.Elements[1].ValueType = type; i = 2; } else { type = LuaDataTypeItem.Error; block.IsError = error = true; i = 1; } for (; i < block.Elements.Count; i++) { if (error) { block.Elements[i].IsError = true; continue; } LuaDataTypeItem chtype; if (type.ValueType == LuaDataType.Function && _vers.TryGetValue(type.Name, out chtype)) { block.Elements[i].ValueType = type; type = chtype; } else { block.Elements[i].IsError = error = true; } } block.IsError = error; block.ValueType = type; return(!error); }
/// <summary> /// 函数类型返回值分析 /// </summary> /// <param name="parent"></param> private void AnalyzeTableBlock(AnalyzeBlock parent) { parent.Name = $"__table__{_tableIndex++}"; _vers.Add(parent.Name, parent.ValueType = new LuaDataTypeItem { Name = parent.Name, Type = parent.Name, ValueType = LuaDataType.Table, ItemType = LuaDataType.Table }); if (parent.Elements.Count < 3) { return; } var mid = parent.Elements[1]; var block = mid as AnalyzeBlock; if (block == null || mid.ItemType != CodeItemType.Separator_Comma) { CheckTableItem(parent, mid, 1); return; } int idx = 1; foreach (var element in block.Elements) { if (element.IsWord) { switch (element.ItemType) { case CodeItemType.Brackets41: case CodeItemType.Brackets42: case CodeItemType.Separator_Comma: continue; } } idx++; CheckTableItem(parent, element, idx); } }
/// <summary> /// 函数类型返回值分析 /// </summary> /// <param name="block"></param> private void CheckFunctionDataType(AnalyzeBlock block) { var ret = block.Elements.FirstOrDefault(p => p.ItemType == CodeItemType.Key_Return) as AnalyzeBlock; if (ret == null || ret.Elements.Count <= 1) { block.ValueType = LuaDataTypeItem.VoidFunction; } else if (ret.Elements[0].ValueType != null) { block.ValueType = ret.Elements[0].ValueType; } else { block.ValueType = new LuaDataTypeItem { ItemType = LuaDataType.Function, Name = ret.Elements[0].Word, ValueType = LuaDataType.Confirm }; } }
/// <summary> /// 逗号组成的多个类型 /// </summary> /// <param name="block"></param> private void CheckCommaDataType(AnalyzeBlock block) { if (block.Parent.ItemFamily == CodeItemFamily.TableDefault) { return; } block.ValueType = new LuaDataTypeItem { Name = block.Name, ItemType = LuaDataType.Function, ValueType = LuaDataType.Mulit, Childs = new List <LuaDataTypeItem>() }; foreach (var element in block.Elements) { if (element.ItemType != CodeItemType.Separator_Comma) { continue; } var word = element as WordUnit; if (word != null) { if (_vers.ContainsKey(word.Word)) { word.ValueType = _vers[word.Word]; } else { _vers.Add(word.Word, word.ValueType = LuaDataTypeItem.Nil); } } else if (element.ValueType == null) { element.ValueType = LuaDataTypeItem.Nil; } block.ValueType.Childs.Add(element.ValueType); } }
/// <summary> /// For组合 /// </summary> /// <returns></returns> public void MergeFor(AnalyzeBlock root) { var cur = root; Stack <AnalyzeBlock> stack = new Stack <AnalyzeBlock>(); int step = 0; foreach (var u in root.ResetElements()) { if (u.IsEmpty) { continue; } var unit = u; var child = unit as AnalyzeBlock; if (child == null) { var word = (WordUnit)unit; if (unit.ItemFamily == CodeItemFamily.Iterator && word.ItemType == CodeItemType.Key_For) { stack.Push(cur); var block = new AnalyzeBlock { Parent = cur, Primary = word, ItemRace = CodeItemRace.Range, ItemFamily = CodeItemFamily.IteratorRange, ItemType = CodeItemType.Key_For }; cur.Append(block); cur = block; step = 1; } else if (step > 0) { step++; if (word.ItemType == CodeItemType.Key_In) { cur.ItemType = CodeItemType.Key_Foreach; } } cur.Append(unit); } else { if (!unit.IsLock && !unit.IsUnit) { MergeFor((AnalyzeBlock)unit); } cur.Append(unit); if (step == 0) { continue; } step++; if (unit.Word != "do") { continue; } if (cur.ItemType != CodeItemType.Key_Foreach) { cur.Elements[1].ValueType = LuaDataTypeItem.NumberValue; } else { cur.Elements[1].ValueLink = cur.Elements[cur.Elements.Count - 2]; } if (stack.Count == 0) { cur.IsError = true; cur = root; } else { cur = stack.Pop(); } step = 0; } } }
/// <summary> /// 括号块组合 /// </summary> /// <returns></returns> public void MergeBracket(AnalyzeBlock root) { var cur = root; Stack <CodeItemType> stack = new Stack <CodeItemType>(); foreach (var unit in root.ResetElements()) { if (unit.IsEmpty) { continue; } var word = unit as WordUnit; if (word == null) { cur.Append(unit); continue; } if (word.IsSpace) { continue; } AnalyzeBlock block; switch (unit.ItemType) { case CodeItemType.Brackets31: var vw = new WordUnit('.') { Start = unit.Start, End = unit.End, IsReplenish = true, IsKeyWord = true, PrimaryLevel = 1, JoinLevel = 1, JoinFeature = JoinFeature.Connect }; vw.SetRace(CodeItemRace.Sentence, CodeItemFamily.Separator, CodeItemType.Separator_Dot); cur.Append(vw); stack.Push(unit.ItemType + 1); block = new AnalyzeBlock { Parent = cur, Primary = word }; cur.Append(block); cur = block; break; case CodeItemType.Brackets21: case CodeItemType.Brackets41: stack.Push(unit.ItemType + 1); block = new AnalyzeBlock { Parent = cur, Primary = word }; cur.Append(block); cur = block; break; case CodeItemType.Brackets22: case CodeItemType.Brackets32: case CodeItemType.Brackets42: if (stack.Count > 0 && stack.Peek() == unit.ItemType) { stack.Pop(); unit.IsError = true; cur.Append(unit); cur.Release(); if (cur.Parent == null) { cur.IsError = true; } else { cur = cur.Parent; } continue; } break; } cur.Append(word); } LinkBarket(root); }
/// <summary> /// 语句块合并 /// </summary> /// <param name="root"></param> /// <returns></returns> private void MergeStatements(AnalyzeBlock root) { MergeRange(root, 10); MergeRange(root, 11); MergeFor(root); }
/// <summary> /// 表子级分析 /// </summary> /// <param name="block"></param> private void AnalyzeTableChild(AnalyzeBlock block) { var name = block.Name ?? block.Word; LuaDataTypeItem type; if (_vers.TryGetValue(name, out type)) { block.ValueType = type; return; } var error = false; var index = 0; var item = block.Elements[index++]; if (item.ItemType == CodeItemType.Call) { if (!AnalyzeCallBlock((AnalyzeBlock)item, out type)) { error = true; } } else { if (_vers.TryGetValue(name, out type)) { item.ValueType = type; } else { error = true; item.ValueType = type = LuaDataTypeItem.Error; } } for (; index < block.Elements.Count; index++) { item = block.Elements[index]; if (error) { item.IsError = true; continue; } if (item.ItemType == CodeItemType.Call) { if (!AnalyzeCallBlock((AnalyzeBlock)item, out type)) { item.IsError = error = true; } else { item.IsError = false; item.ValueType = type; } } else { if (type.ValueType != LuaDataType.Table) { item.IsError = error = true; continue; } LuaDataTypeItem chType; if (_vers.TryGetValue(type.Name, out chType)) { item.IsError = false; item.ValueType = type = chType; } else { error = true; item.IsError = true; item.ValueType = type = LuaDataTypeItem.Error; } } } if (error || type == null) { type = LuaDataTypeItem.Error; } _vers.Add(name, type); block.ValueType = type; }
/// <summary> /// 分级组合 /// 0 括号块组合(不使用此方法) /// 1 .;单词粘连组合 /// 2 一元操作符组合(not # -) /// 3 串联组合(.. ^) /// 4 乘除余指数(* / %) /// 5 加减(+ -) /// 6 比较(== ~大小于) /// 7 逻辑(and) /// 8 逻辑(or) /// 9 赋值(=) /// </summary> /// <param name="root"></param> /// <param name="level"></param> /// <returns></returns> public void MergeSimpleBlock(AnalyzeBlock root, int level) { AnalyzeUnitBase preUnit = null; var joinNext = false; var array = root.Elements.ToArray(); root.Elements.Clear(); foreach (var unit in array) { if (unit.IsEmpty) { continue; } if (unit.IsContent) { root.Append(unit); joinNext = false; preUnit = null; continue; } var block = unit as AnalyzeBlock; if (block != null) { if (!unit.IsLock && !unit.IsUnit) { MergeSimpleBlock(block, level); } if (!joinNext) { root.Append(block); preUnit = block; } else { ((AnalyzeBlock)preUnit).Append(block); joinNext = false; } continue; } var word = (WordUnit)unit; if (word.JoinLevel == level) { switch (word.JoinFeature) { case JoinFeature.Front: var newBlock = new AnalyzeBlock { Primary = word }; root.Append(newBlock); newBlock.Append(unit); preUnit = newBlock; joinNext = true; continue; case JoinFeature.TowWay: newBlock = new AnalyzeBlock { Primary = word }; if (preUnit == null) { newBlock.IsError = true; } else { root.Elements.Remove(preUnit); newBlock.Append(preUnit); } root.Append(newBlock); newBlock.Append(unit); preUnit = newBlock; joinNext = true; continue; } } if (!joinNext) { root.Append(word); if (!word.IsSpace && unit.ItemRace != CodeItemRace.Assist) { preUnit = level <= 6 && unit.ItemRace == CodeItemRace.Range ? null : word; } continue; } if (word.Char == ';')//终止符号出错 { ((AnalyzeBlock)preUnit).IsError = true; joinNext = false; preUnit = null; continue; } ((AnalyzeBlock)preUnit).Append(unit); if (word.IsSpace || unit.ItemRace == CodeItemRace.Assist) { continue; } if (level < 6) { preUnit.IsError = unit.ItemRace == CodeItemRace.Range; } joinNext = false; } }
/// <summary> /// 串联 /// </summary> /// <param name="root"></param> /// <param name="level"></param> /// <returns></returns> public void ConnectBlock(AnalyzeBlock root, int level) { AnalyzeUnitBase pre = null; var step = 0; AnalyzeBlock cur = root; foreach (var unit in root.ResetElements()) { if (unit.IsEmpty) { continue; } var block = unit as AnalyzeBlock; if (block != null) { if (!unit.IsLock && !unit.IsUnit) { ConnectBlock(block, level); } pre = block; } else { if (unit.JoinLevel == level && unit.JoinFeature == JoinFeature.Connect) { if (step == 0) { cur = new AnalyzeBlock { Primary = (WordUnit)unit }; if (pre != null) { cur.Append(pre); root.Elements.RemoveAt(root.Elements.Count - 1); } else { cur.IsError = true; } root.Append(cur); } step = 1; cur.Append(unit); continue; } pre = ((WordUnit)unit).IsPunctuate || ((WordUnit)unit).IsKeyWord ? null : unit; } switch (step) { case 0: root.Append(unit); break; case 1: step = 2; cur.Append(unit); break; default: step = 0; root.Append(unit); break; } } }
private void PrintTree(AnalyzeBlock root, StringBuilder builder, int level) { foreach (var unit in root.Elements) { if (unit.IsContent) { builder.AppendLine(); if (level > 0) { builder.Append('_', level); } builder.Append("***"); continue; } var block = unit as AnalyzeBlock; if (block != null) { if (unit.IsLock) { builder.AppendLine(); if (level > 0) { builder.Append('_', level); } foreach (var word in block.Elements.OfType <WordUnit>()) { builder.Append(word.IsLine ? " " : word.Word); } continue; } if (unit.IsError) { builder.AppendLine(); if (level > 0) { builder.Append('_', level); } builder.Append("×"); } PrintTree(block, builder, level + 4); } else { var word = (WordUnit)unit; if (!word.IsSpace) { builder.AppendLine(); if (level > 0) { builder.Append('_', level); } if (unit.IsError) { builder.Append("×"); } builder.Append(word.Word); if (word.JoinLevel >= 0) { builder.AppendFormat(" [{0}]", word.JoinLevel); } } } } }
/// <summary> /// 常量组合 /// </summary> /// <returns></returns> public void MergeBlockValue() { Root = new AnalyzeBlock(); var cur = Root; var preType = 0; foreach (var word in Words) { if (word.IsEmpty) { continue; } int type; switch (word.ItemType) { case CodeItemType.SignleRem: case CodeItemType.MulitRem: case CodeItemType.TemplateConfig: case CodeItemType.TemplateRem: type = 1; break; case CodeItemType.Content: type = 2; break; case CodeItemType.String: type = 3; break; default: if (preType > 0) { cur.Release(); cur = cur.Parent; preType = 0; } cur.Append(word); continue; } if (preType != type) { var block = new AnalyzeBlock { IsUnit = true, Parent = cur, Primary = word, IsContent = type == 2, IsLock = true }; if (type == 1) { block.SetRace(CodeItemRace.Assist, CodeItemFamily.Rem, CodeItemType.MulitRem); } else { block.SetRace(CodeItemRace.Value, CodeItemFamily.Constant, CodeItemType.String); } cur.Append(block); cur = block; preType = type; } cur.Append(word); } if (preType > 0) { cur.Release(); } }