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