/// <summary> /// 下一个字符是否符合期望条件 /// </summary> /// <param name="codeElement">当前合并内容</param> /// <param name="condition">是否期望条件</param> /// <param name="succeedAction">如果符合条件,加入节点前的操作</param> /// <param name="canSpace">是否允许空白符间隔</param> /// <returns></returns> protected bool TryGoNextWithCondition(AnalyzeElement codeElement, Func <WordElement, bool> condition, Action <AnalyzeElement> succeedAction, bool canSpace) { var idx = CurWordIndex; idx++; if (idx == WordElements.Count) { return(false); } if (canSpace && WordElements[idx].IsSpace) { idx++; } if (idx >= WordElements.Count || !condition(WordElements[idx])) { return(false); } succeedAction?.Invoke(codeElement); while (CurWordIndex < idx) { codeElement.Append(WordElements[++CurWordIndex]); } return(true); }
/// <summary> /// 查找成对的符号 /// </summary> /// <param name="codeElement">语言节点</param> /// <param name="start">开始字符</param> /// <param name="end">结束</param> /// <param name="includeStartEnd">结果是否包括前后字符</param> /// <param name="skipCur">是否先行跳过当前字符</param> /// <returns></returns> protected void FindCouple(AnalyzeElement codeElement, char start, char end, bool includeStartEnd, bool skipCur = false) { WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); if (skipCur) { CurWordIndex++; } //确认开始字符是否当前字符,如果不是,当前可为空白且下一个必须是前导字符 if (WordElements[CurWordIndex].Char != start) { if (CurWordIndex + 1 < WordElements.Count && WordElements[CurWordIndex + 1].Char == start) { if (includeStartEnd) { codeElement.Append(WordElements[CurWordIndex]); } CurWordIndex++; if (includeStartEnd) { codeElement.Append(WordElements[CurWordIndex]); } } else { return; } } else if (includeStartEnd) { codeElement.Append(WordElements[CurWordIndex]); } var block = 1; var preChar = '\0'; for (CurWordIndex++; CurWordIndex < WordElements.Count; CurWordIndex++) { var curElement = WordElements[CurWordIndex]; if (curElement.Char == start) { block++; } else if (curElement.Char == end) { --block; } if (block == 0) //成对结束 { curElement.SetRace(CodeItemRace.Assist, CodeItemFamily.Range); if (includeStartEnd) { codeElement.Append(curElement); } return; } //标点处理,以防止特殊情况的污染(注释,字符串,字符) MergeLanWord(codeElement, ref preChar); } }
/// <summary> /// 重置当前内容节点 /// </summary> /// <param name="element"></param> protected void ResetContentElement(WordElement element = null) { ContentElement = new AnalyzeElement(element) { IsContent = true }; TemplateElements.Add(ContentElement); }
/// <summary> /// 直到期望字符出现结束 /// </summary> /// <param name="codeElement">当前合并内容</param> /// <param name="word">这个字符期望的内容</param> /// <returns></returns> protected void StepEndWord(AnalyzeElement codeElement, string word) { while (++CurWordIndex < WordElements.Count) { var el = WordElements[CurWordIndex]; codeElement.Append(el); if (el.RealWord == word) { return; } } }
/// <summary> /// 合并到行尾结束的对象 /// </summary> /// <param name="codeElement">代码块</param> protected void MergeToLineEnd(AnalyzeElement codeElement) { for (CurWordIndex++; CurWordIndex < WordElements.Count; CurWordIndex++) { var curElement = WordElements[CurWordIndex]; if (curElement.IsLine) //行已结束 { --CurWordIndex; //回退 return; } codeElement.Append(curElement); } }
public void MergeLanWord() { TemplateElements.Clear(); ContentElement = null; var el = new AnalyzeElement(); char pre = '\0'; for (CurWordIndex = 0; CurWordIndex < WordElements.Count; CurWordIndex++) { MergeLanWord(el, ref pre); } TemplateElements.Add(el); }
/// <summary> /// 检查是否为代码块结束标记,不同语言不同,C#是@},LUA是@end /// </summary> /// <param name="codeElement">代码块</param> /// <returns></returns> protected bool CheckIsCodeBlockEnd(AnalyzeElement codeElement) { if (IsWithLineStart() && IsWithLineEnd()) { ContentElement.Elements.Remove(WordElements[CurWordIndex - 2]); //空行 ContentElement.Elements.Remove(WordElements[CurWordIndex - 1]); //空行 codeElement.ItemRace = CodeItemRace.Range; codeElement.Append(WordElements[CurWordIndex]); JoinCode(codeElement); return(true); } CurWordIndex--; return(false); }
/// <summary> /// 合并单元 /// </summary> /// <param name="element">代码的基本单元</param> public void AddAssist(AnalyzeElement element) { if (element == null || Assists.Contains(element)) { return; } if ((Start < 0 || Start > element.Start) && element.Start >= 0) { Start = element.Start; } if (End < element.End && element.End >= 0) { End = element.End; } Assists.Add(element); }
/// <summary> /// 处理多行嵌入代码 /// </summary> /// <param name="codeElement"></param> /// <remarks> /// 如果后面是@,则后续还是代码,直到一个有且只有两个@字符的行 /// </remarks> protected void CheckMulitCode(AnalyzeElement codeElement) { if (!NextWithCondition("@", false)) { return; } var preChar = '\0'; WordElements[++CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); var waiting = new List <WordElement>(); for (CurWordIndex++; CurWordIndex < WordElements.Count; CurWordIndex++) { if (WordElements[CurWordIndex].IsLine) { if (waiting.Count == 3) { waiting[1].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); waiting[2].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); CurWordIndex--; return; } foreach (var item in waiting) { codeElement.Append(item); } waiting.Clear(); waiting.Add(WordElements[CurWordIndex]); continue; } if (waiting.Count > 0 && waiting.Count < 3 && WordElements[CurWordIndex].Char == '@') { waiting.Add(WordElements[CurWordIndex]); continue; } foreach (var item in waiting) { codeElement.Append(item); } waiting.Clear(); MergeLanWord(codeElement, ref preChar); } foreach (var item in waiting)//补回去 { codeElement.Append(item); } }
/// <summary> /// 前进到下一个字符 /// </summary> /// <param name="codeElement">当前合并内容</param> /// <param name="word">这个字符期望的内容(不影响合并,但影响返回值)</param> /// <param name="canSpace">是否允许空白符间隔</param> /// <returns></returns> protected bool GoNextWithWord(AnalyzeElement codeElement, string word, bool canSpace = true) { CurWordIndex++; if (CurWordIndex == WordElements.Count) { return(false); } if (canSpace && WordElements[CurWordIndex].IsSpace) { codeElement.Append(WordElements[CurWordIndex++]); } if (CurWordIndex == WordElements.Count) { return(false); } codeElement.Append(WordElements[CurWordIndex]); return(WordElements[CurWordIndex].RealWord == word); }
/// <summary> /// 查找单个变量 /// </summary> /// <param name="codeElement">代码块</param> /// <param name="joinChar">变量连接字符</param> /// <returns></returns> protected void FindVariable(AnalyzeElement codeElement, params char[] joinChar) { codeElement.ItemRace = CodeItemRace.Variable; codeElement.Append(WordElements[CurWordIndex]); if (CurWordIndex + 1 == WordElements.Count) { return; } var word = WordElements[++CurWordIndex]; //第一个字符后不跟期望标点,不可再拼接 if (!word.IsPunctuate || !joinChar.Any(p => p == word.Char)) { //当前标点作为普通内容,故做回退处理 --CurWordIndex; return; } for (; CurWordIndex < WordElements.Count; CurWordIndex++) { word = WordElements[CurWordIndex]; if (word.IsPunctuate) { //当前为分隔符且后一个为字符 if (!joinChar.Any(p => p == word.Char) || !NextWithCondition(p => p.IsWord, false)) { //当前标点作为普通内容,故做回退处理 --CurWordIndex; return; } codeElement.Append(word); } else { codeElement.Append(word); //当前为字符且后一个为分隔符 if (!NextWithCondition(p => joinChar.Any(ch => ch == p.Char), false)) { return; } } } }
/// <summary> /// 下一个字符是否为期望字符,如果是,合并之 /// </summary> /// <param name="codeElement">当前合并内容</param> /// <param name="word">这个字符期望的内容</param> /// <param name="canSpace">是否允许空白符间隔</param> /// <returns></returns> protected bool TryGoNextWithWord(AnalyzeElement codeElement, string word, bool canSpace) { var idx = CurWordIndex; idx++; if (idx == WordElements.Count) { return(false); } if (canSpace && WordElements[idx].IsSpace) { idx++; } if (idx >= WordElements.Count || WordElements[idx].RealWord != word) { return(false); } while (CurWordIndex < idx) { codeElement.Append(WordElements[++CurWordIndex]); } return(true); }
/// <summary> /// 处理当前语言内容 /// </summary> /// <param name="codeElement">语言节点</param> /// <param name="preChar"></param> public abstract void MergeLanWord(AnalyzeElement codeElement, ref char preChar);
/// <summary> /// 下一个字符是否符合期望条件 /// </summary> /// <param name="codeElement">当前合并内容</param> /// <param name="condition">是否期望条件</param> /// <param name="canSpace">是否允许空白符间隔</param> /// <returns></returns> protected bool TryGoNextWithCondition(AnalyzeElement codeElement, Func <WordElement, bool> condition, bool canSpace) { return(TryGoNextWithCondition(codeElement, condition, null, canSpace)); }
/// <summary> /// 组合代码 /// </summary> /// <param name="codeElement">代码块</param> protected virtual void JoinCode(AnalyzeElement codeElement) { codeElement.ItemRace = CodeItemRace.Sentence; TemplateElements.Add(codeElement); ResetContentElement(); }
/// <summary> /// 检查标点打头的代码块 /// </summary> /// <returns></returns> protected virtual bool CheckPunctuateStartCode() { var codeElement = new AnalyzeElement(); switch (WordElements[CurWordIndex].Char) { case '@': WordElements[CurWordIndex - 1].SetRace(CodeItemRace.Assist, CodeItemFamily.None); return(false); //两个@为一个@ default: CurWordIndex--; //其它标点回退,此时@为普通字符 return(false); case '*': //@*...*@为注释,跳过 WordElements[CurWordIndex - 1].SetRace(CodeItemRace.Assist, CodeItemFamily.None); WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.None); SkipRazorRem(); WordElements[CurWordIndex - 1].SetRace(CodeItemRace.Assist, CodeItemFamily.None); WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.None); return(true); case '#': //@#...#@为文档配置 WordElements[CurWordIndex - 1].SetRace(CodeItemRace.Assist, CodeItemFamily.None); WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.None); ReadFileRem(); WordElements[CurWordIndex - 1].SetRace(CodeItemRace.Assist, CodeItemFamily.None); WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.None); return(true); case '-': //单行@-表示单行代码 WordElements[CurWordIndex - 1].SetRace(CodeItemRace.Assist, CodeItemFamily.None); WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.None); if (!IsWithLineStart()) { CurWordIndex--; //其它标点回退,此时@为普通字符 return(false); } if (IsWithLineEnd()) { return(true); //跳过空语句 } MergeToLineEnd(codeElement); codeElement.SetRace(CodeItemRace.Assist, CodeItemFamily.Rem); break; case '(': //@()小括号配对变量块 WordElements[CurWordIndex - 1].SetRace(CodeItemRace.Assist, CodeItemFamily.Sharp); WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); FindCouple(codeElement, '(', ')', false); codeElement.IsBlock = true; foreach (var item in codeElement.Elements) { item.Words.ForEach(p => p.IsBlock = true); } if (CurWordIndex < WordElements.Count) { WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); } break; case '{': //@{}多行代码块 if (!IsWithLineStart() || !IsWithLineEnd()) { CurWordIndex--; //其它标点回退,此时@为普通字符,{会下一次被普通处理 return(false); } WordElements[CurWordIndex - 1].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); FindCouple(codeElement, '{', '}', false); if (CurWordIndex < WordElements.Count) { WordElements[CurWordIndex].SetRace(CodeItemRace.Assist, CodeItemFamily.Range); } break; } JoinCode(codeElement); return(true); }