/// <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);
 }
Example #8
0
 /// <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);
        }