/// <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="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> /// <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> /// <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); } }
/// <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="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); }