/// <summary> 对指令文本进行匹配检查 </summary> public bool Match(string input) { // 格式化指令文本 ReplaceFormat iformat = new ReplaceFormat(input); switch (Type) { // 非法格式不能匹配 case TYPE_INVALID: return(false); // 指令格式逐个匹配 case TYPE_LADDER: for (int i = 0; i < ArgsCount; i++) { // 【任意后缀】参数,匹配成功 if (GetArgs(i).Type == ARG_ANYSUFFIX) { return(true); } // 超过了指令文本的参数个数,匹配失败 if (iformat.ArgsCount <= i) { return(false); } // 该项匹配失败 if (!Match(GetArgs(i), iformat.GetArgs(i))) { return(false); } } // 通过所有检查,匹配成功 return(true); // 寄存器格式需要查找 case TYPE_REGISTER: // 指令无参数 if (iformat.ArgsCount < 2) { return(false); } // 查找是否存在符合匹配的指令参数 for (int i = 1; i < iformat.ArgsCount; i++) { if (Match(GetArgs(0), iformat.GetArgs(i))) { return(true); } } // 未找到,匹配失败 return(false); // 其他格式不能匹配 default: return(false); } }
/// <summary> /// 根据该格式进行替换操作,生成替换命令 /// </summary> /// <param name="prototype">查找格式</param> /// <param name="input">指令文本</param> /// <param name="x">元件X坐标</param> /// <param name="y">元件Y坐标</param> /// <param name="ldvmodel">所属网络</param> /// <param name="lnvmodel">所属程序</param> /// <returns>替换命令</returns> public NetworkReplaceElementsCommand Replace ( ReplaceFormat prototype, string input, int x, int y, LadderDiagramViewModel ldvmodel, LadderNetworkViewModel lnvmodel ) { // 将指令文本转为正则格式 ReplaceFormat iformat = new ReplaceFormat(input); // 要匹配的参数项 ReplaceFormatArg arg; arg.Type = ARG_INVAILD; arg.Low = arg.High = arg.OLow = arg.OHigh = 0; arg.Offset = arg.Base = arg.Text = String.Empty; // 替换后的指令文本 string output = String.Empty; // 检查原指令的每个参数 for (int i = 0; i < iformat.ArgsCount; i++) { // 替换格式为寄存器格式 if (prototype.Type == TYPE_REGISTER) { // 查找格式也为寄存器格式,并且不匹配 if (Type == TYPE_REGISTER && !Match(prototype.GetArgs(0), iformat.GetArgs(i))) { // 保留原样 output += iformat.GetArgs(i).Text + " "; } else { arg.Type = ARG_INVAILD; // 寄存器格式只读第一个参数 if (Type == TYPE_REGISTER) { arg = GetArgs(0); } // 指令格式读相应位置的参数 else if (i <= ArgsCount) { arg = GetArgs(i); } // 当前的参数格式 switch (arg.Type) { // 指令名称 case ARG_INSTRUCTION: // 对应位置不是指令时保留原样 if (iformat.GetArgs(i).Type != ARG_INSTRUCTION) { output += iformat.GetArgs(i).Text + " "; break; } // 替换对应的指令名称 output += arg.Text + " "; break; // 寄存器 case ARG_REGISTER: // 对应位置不是寄存器时保留原样 if (iformat.GetArgs(i).Type != ARG_REGISTER && iformat.GetArgs(i).Type != ARG_UNDEFINED) { output += iformat.GetArgs(i).Text + " "; break; } // 判断查找模型的这个参数是否制定唯一的寄存器 bool isunique = false; isunique = (!prototype.GetArgs(0).Base.Equals(arg.Base)); isunique |= (prototype.GetArgs(0).Low == prototype.GetArgs(0).High); isunique |= (arg.Low == arg.High); int baseid = arg.Low; // 不是唯一的情况下需要地址转移 if (!isunique) { baseid += iformat.GetArgs(i).Low - prototype.GetArgs(0).Low; } // 得到对应的转换后的寄存器的文本 output += String.Format("{0:s}{1:d}", arg.Base, baseid); if (!arg.Offset.Equals(String.Empty)) { output += String.Format("{0:s}{1:d}", arg.Offset, arg.OLow); } output += " "; break; // 其他格式 default: output += iformat.GetArgs(i).Text + " "; break; } } continue; } // 超出的部分保留原样 if (i >= ArgsCount) { output += iformat.GetArgs(i).Text + " "; continue; } // 根据当前参数的格式 switch (GetArgs(i).Type) { // 指令名称 case ARG_INSTRUCTION: output += GetArgs(i).Text + " "; break; // 寄存器 case ARG_REGISTER: // 策略和上面一致 bool isunique = false; isunique |= (i >= prototype.ArgsCount); if (!isunique) { isunique = (prototype.GetArgs(i).Low == prototype.GetArgs(i).High); isunique |= (GetArgs(i).Low == GetArgs(i).High); } int baseid = GetArgs(i).Low; if (!isunique) { baseid += iformat.GetArgs(i).Low - prototype.GetArgs(i).Low; } output += String.Format("{0:s}{1:d}", GetArgs(i).Base, baseid); if (!GetArgs(i).Offset.Equals(String.Empty)) { output += String.Format("{0:s}{1:d}", GetArgs(i).Offset, GetArgs(i).OLow); } output += " "; break; // 其他格式 default: output += iformat.GetArgs(i).Text + " "; break; } } // 建立命令并返回 NetworkReplaceElementsCommand command = null; int rectX = ldvmodel.SelectionRect.X; ldvmodel.RegisterInstructionInput( output, x, y, lnvmodel, ref command, ref rectX); return(command); }