/// <summary> /// Проверка на метку /// </summary> public static bool isLabel(string label) { if (!Utils.isOperation(label)) { return(false); } foreach (string e in Utils.keyWords) { if (label == e) { return(false); } } if (!isNotRussian(label)) { return(false); } if (TMO.isInTMO(label)) { return(false); } if (Global.isInGlobal(label)) { return(false); } return(true); }
/// <summary> /// Проверка строки с операцией MACRO /// </summary> /// <param name="se">строка с операцией MACRO</param> public static void checkMACRO(SourceEntity se, bool macroFlag) { if (se.sourceString.Contains(":")) { throw new SPException("При объявлении макроса не должно быть меток: " + se.sourceString); } if (String.IsNullOrEmpty(se.label) || !Utils.isLabel(se.label)) { throw new SPException("Имя макроса некорректно: " + se.sourceString); } if (TMO.isInTMO(se.label)) { throw new SPException("Макрос " + se.label + " уже описан: " + se.sourceString); } //if (macroFlag == true) //{ // throw new SPException("Макроопределения внутри макроса запрещены: " + se.sourceString); //} //if (se.operands.Count != 0) //{ // throw new SPException("У макроса не должно быть параметров: " + se.sourceString); //} foreach (string o in se.operands) { if (se.operands.Count(p => p == o) > 1) { throw new SPException("Имя параметра \"" + o + "\" повторяется: " + se.sourceString); } if (!Utils.isLabel(o)) { throw new SPException("Имя параметра \"" + o + "\" некорректно: " + se.sourceString); } foreach (TMOEntity te in TMO.entities) { foreach (string par in te.parameters) { if (par == o) { throw new SPException("Имя параметра " + o + " уже используется в другом макросе: " + se.sourceString); } } } Utils.checkNames(o); if (o == se.label) { throw new SPException("Имя параметра " + o + " некорректно (совпадает с названием макроса): " + se.sourceString); } } Utils.checkNames(se.label); }
/// <summary> /// Проверка макроподстановки /// </summary> public static void checkMacroRun(SourceEntity se, TMOEntity parent, TMOEntity child) { //TMOEntity current = parent; //List<TMOEntity> list = new List<TMOEntity>(); //while (current.prev != null) //{ // if (list.Contains(current)) // { // throw new SPException("Перекрестные ссылки и рекурсия запрещены."); // } // list.Add(current); // current = current.prev; //} if (TMO.isInTMO(child.name) && parent.name == child.name) { throw new SPException("Макрос \"" + child.name + "\" не может быть вызван из себя (Рекурсия запрещена)."); } //if (TMO.isInTMO(child.name) && !parent.localTMO.Contains(child)) //{ // throw new SPException("Макрос " + child.name + " не входит в область видимости " + // (parent.name == "root" ? "основной программы" : "тела макроса " + parent.name) + "."); //} }
/// <summary> /// Шаг первого прохода /// </summary> public void firstRunStep(SourceEntity se, TMOEntity te) { String operation = se.operation; String label = se.label; List <String> operands = se.operands; try { CheckSourceEntity.checkLabel(se); if (operation == "END") { CheckSourceEntity.checkEND(se, this.macroFlag, this.macroName); result.Add(Utils.print(se)); } else if (operation == "GLOBAL" && this.macroFlag == false) { CheckSourceEntity.checkGLOBAL(se); if (operands.Count == 1) { Global.entities.Add(new GlobalEntity(operands[0], null)); } else { Global.entities.Add(new GlobalEntity(operands[0], Int32.Parse(operands[1]))); } } else if (operation == "SET" && this.macroFlag == false) { CheckSourceEntity.checkSET(se, te); Global.searchInGlobal(se.operands[0]).value = Int32.Parse(se.operands[1]); } else if (operation == "INC" && this.macroFlag == false) { CheckSourceEntity.checkINC(se, te); Global.searchInGlobal(operands[0]).value++; } else if (operation == "MACRO") { if (te != TMO.root) { throw new SPException("Макроопределения внутри макросов запрещены"); } CheckSourceEntity.checkMACRO(se, macroFlag); TMO.entities.Add(new TMOEntity() { name = label, parameters = se.operands }); this.macroFlag = true; this.macroName = label; } else if (operation == "MEND") { if (te != TMO.root) { throw new SPException("Макроопределения внутри макросов запрещены"); } CheckSourceEntity.checkMEND(se, macroFlag); foreach (SourceEntity mc in mbMacroCall) { if (mc.operation == this.macroName) { TMOEntity currentTe = TMO.searchInTMO(this.macroName); CheckSourceEntity.checkMacroSubstitution(mc, currentTe); List <SourceEntity> res = CheckBody.checkMacroBody(currentTe, operands); // результат макроподстановки List <SourceEntity> macroSubs = new List <SourceEntity>(); foreach (SourceEntity str in res) { macroSubs.Add(Utils.print(str)); } // Заменяем в результате макровызов на результат макроподстановки for (int i = 0; i < this.result.Count; i++) { if (this.result[i].operation == mc.operation && this.result[i].isRemove == "true") { this.result.Remove(this.result[i]); this.result.InsertRange(i, macroSubs); i += macroSubs.Count - 1; } } } } TMOEntity curTe = TMO.searchInTMO(this.macroName); curTe.IsFinished = true; var prevTe = TMO.GetPrevNotFinishedMacro(); if (prevTe != null) { this.macroFlag = true; this.macroName = prevTe.name; } else { this.macroFlag = false; this.macroName = null; } } else { if (this.macroFlag == true) { TMO.searchInTMO(this.macroName).body.Add(se); } else { if (te == TMO.root && (operation == "WHILE" || operation == "ENDW")) { throw new SPException("Использование директивы " + operation + " возможно только в теле макроса: " + se.sourceString); } // макровызов if (TMO.isInTMO(operation)) { TMOEntity currentTe = TMO.searchInTMO(operation); CheckSourceEntity.checkMacroSubstitution(se, currentTe); CheckBody.checkMacroRun(se, te, currentTe); List <SourceEntity> res = CheckBody.checkMacroBody(currentTe, operands); foreach (SourceEntity str in res) { result.Add(Utils.print(str)); } //if (te == TMO.root) //{ //} //else //{ // throw new SPException("Макровызовы внутри макроса запрещены"); //} } else { // Добавляем строку в список подозрительных на макровызов и в результат se = Utils.print(se); if (te == TMO.root && macroFlag == false) { se.isRemove = "true"; mbMacroCall.Add(se); } result.Add(se); } } } } catch (SPException ex) { throw new SPException(ex.Message); } }