Ejemplo n.º 1
0
        /// <summary>
        /// 调度参数解析
        /// </summary>
        /// <param name="raw">原始字符串</param>
        /// <param name="env">环境</param>
        /// <param name="args">参数</param>
        /// <param name="reply">回复消息</param>
        /// <returns>是否符合该节点</returns>
        public DispatchResult Dispatch(StringReader reader, TEnv env, Args args, out string reply)
        {
            string err = "参数匹配错误";

            reader.SkipWhiteSpace();

            // 匹配参数
            object arg = null;

            if (Spread)   // 收集所有剩下的参数
            {
                List <object> list = new List <object>();
                while (reader.HasNext && Parser.TryParse(reader, out arg))
                {
                    list.Add(arg);
                    reader.SkipWhiteSpace();
                }
                if (list.Count == 0)
                {
                    reply = err;
                    return(DispatchResult.Unmatched);
                }
                arg = list.ToArray();
            }
            else     // 仅检测一个参数
            {
                if (!Parser.TryParse(reader, out arg))
                {
                    reply = err;
                    return(DispatchResult.Unmatched);
                }
            }

            // 预处理得到的参数,包括参数的可行检测,以及转换
            if (Process != null && !Process(env, args, out arg))
            {
                reply = err;
                return(DispatchResult.Unmatched);
            }

            // 如果有参数名,则将该值赋予参数
            if (!string.IsNullOrEmpty(ParamName))
            {
                args[ParamName] = arg;
            }

            DispatchResult childResult = DispatchResult.Unmatched;

            reader.SkipWhiteSpaceExcept(DictArgSeperators);
            // 判断映射参数部分是否还未开始
            if (reader.HasNext && DictArgSeperators.IndexOf(reader.Peek()) < 0)
            {
                int start = reader.Cursor;
                childResult = DispatchResult.MatchedAll;
                // 优先匹配子节点,执行子节点的逻辑
                foreach (CommandNode <TEnv> child in GetRevelentNodes(reader))
                {
                    // 执行子节点的调度
                    childResult = child.Dispatch(reader, env, args.Derives(), out reply);
                    if (childResult == DispatchResult.MatchedAll)
                    {
                        // 如果某个子节点全部匹配则完美收官,返回结果
                        return(childResult);
                    }
                    else if (childResult == DispatchResult.MatchedSelf)
                    {
                        // 如果某个子节点只匹配了自身,则结束遍历,但是暂不返回结果
                        err           = reply;
                        reader.Cursor = start;
                        break;
                    }
                    // 如果某个子节点也根本不匹配,则继续遍历下一个节点
                    reader.Cursor = start;
                }
            }
            // 执行到这里,说明子节点没有一个是完美匹配的
            // 如果自身节点本来有执行逻辑的话,则忽略后续参数,执行自身节点的执行逻辑,并判定为参数匹配成功
            if (Executor != null)
            {
                // 解析映射参数
                Args dict = new Args();
                if (Mapper != null)
                {
                    reader.SkipTo(DictArgSeperators);
                    Mapper.Parse(reader, dict, out string dictErr);
                }
                reply = Executor(env, args, dict);
                return(DispatchResult.MatchedAll);
            }
            else if (childResult == DispatchResult.MatchedSelf)
            {
                reply = err;
                return(childResult);
            }
            // 到这里说明自己没有执行逻辑,而子节点也一个都没有匹配成功,则视为只匹配了自身
            reader.SkipWhiteSpace();
            reply = new StringBuilder()
                    .AppendLine("期待:" + string.Join(",", GetTips()))
                    .Append("得到:" + (reader.HasNext ? reader.PeekRest() : "<空>"))
                    .ToString();
            return(DispatchResult.MatchedSelf);
        }