Exemplo n.º 1
0
 /// <summary>
 /// Проверка строки с операцией INC
 /// </summary>
 /// <param name="se">строка с операцией INC</param>
 public static void checkINC(SourceEntity se, TMOEntity te)
 {
     if (!String.IsNullOrEmpty(se.label))
     {
         throw new SPException("В директиве INC метки не должно быть: " + se.sourceString);
     }
     if (se.operands.Count == 1)
     {
         if (!Global.isInGlobal(se.operands[0]))
         {
             throw new SPException("Некорректное имя глобальной переменной: " + se.sourceString);
         }
         if (Global.searchInGlobal(se.operands[0]).value == null)
         {
             throw new SPException("Глобальной переменной " + se.operands[0] + " не присвоено значение.");
         }
         foreach (Dictionary <List <string>, TMOEntity> dict in Global.whileVar)
         {
             if (dict.Keys.First().Contains(se.operands[0]) && dict.Values.First() != te)
             {
                 throw new SPException("Глобальная переменная " + se.operands[0] + " используется как счетчик в цикле: " + se.sourceString);
             }
         }
     }
     else
     {
         throw new SPException("Некорректное количество операндов в директиве INC: " + se.sourceString);
     }
 }
Exemplo n.º 2
0
 /// <summary>
 /// Проверка строки с операцией SET
 /// </summary>
 /// <param name="se">строка с операцией SET</param>
 public static void checkSET(SourceEntity se, TMOEntity te)
 {
     if (!String.IsNullOrEmpty(se.label))
     {
         throw new SPException("В директиве SET метки не должно быть: " + se.sourceString);
     }
     if (se.operands.Count == 2)
     {
         if (!Global.isInGlobal(se.operands[0]))
         {
             throw new SPException("Некорректное имя глобальной переменной: " + se.sourceString);
         }
         int temp;
         if (Int32.TryParse(se.operands[1], out temp) == false)
         {
             throw new SPException("Некорректное значение глобальной переменной: " + se.sourceString);
         }
         foreach (Dictionary <List <string>, TMOEntity> dict in Global.whileVar)
         {
             if (dict.Keys.First().Contains(se.operands[0]) && dict.Values.First() != te)
             {
                 throw new SPException("Глобальная переменная " + se.operands[0] + " используется как счетчик в цикле: " + se.sourceString);
             }
         }
     }
     else
     {
         throw new SPException("Некорректное количество операндов в директиве SET: " + se.sourceString);
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// Поиск макроса в ТМО по имени
        /// </summary>
        public static TMOEntity searchInTMO(string name)
        {
            TMOEntity result = (from TMOEntity te in TMO.entities
                                where te.name == name
                                select te).SingleOrDefault <TMOEntity>();

            return(result);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Проверка body макроса на GLOBAL, SET и формирование выходного body
        /// </summary>
        /// <param name="se">макрос TMOEntity</param>
        public static List <SourceEntity> checkMacroBody(TMOEntity te, List <String> operands)
        {
            //foreach (SourceEntity se in te.body)
            //{
            //    if (TMO.isInTMO(se.operation))
            //    {
            //        throw new SPException("Макровызовы внутри макроса запрещены: " + se.sourceString);
            //    }
            //}
            List <SourceEntity> result = te.invoke(operands.ToArray());

            return(result);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Проверяет макрос на наличие меток
        /// </summary>
        public static void CheckMacroLabels(TMOEntity te)
        {
            List <SourceEntity> result = new List <SourceEntity>();

            foreach (SourceEntity se in te.body)
            {
                result.Add(se.Clone());
            }
            //// Определяем метки, используемые при AGO
            //foreach (SourceEntity se in result)
            //{
            //    if (se.operation == "AGO" && se.operands.Count > 0 && !te.agoLabels.Contains(se.operands[0]))
            //    {
            //        te.agoLabels.Add(se.operands[0]);
            //    }
            //    if (se.operation == "AIF" && se.operands.Count > 1 && !te.agoLabels.Contains(se.operands[1]))
            //    {
            //        te.agoLabels.Add(se.operands[1]);
            //    }
            //}
            //формируется локальная область видимости
            // Список меток, которые являютс ячастью AGO, и уже найдены
            //List<string> markedLabels = new List<string>();
            //foreach (SourceEntity se in result)
            //{
            //if (!String.IsNullOrEmpty(se.label))
            //{
            //if (!Utils.isLabel(se.label))
            //{
            //throw new SPException("Метки внутри макроса " + te.name + " запрещены");
            //}
            //if (!te.agoLabels.Contains(se.label))
            //{
            //    throw new SPException("Метки внутри макроса " + te.name + " запрещены");
            //}
            //else
            //{
            //    if (markedLabels.Contains(se.label))
            //    {
            //        throw new SPException("Повторное описание метки " + se.label + " в макросе " + te.name);
            //    }
            //    markedLabels.Add(se.label);
            //}
            //    }
            //}
            //if (te.agoLabels.Count != markedLabels.Count)
            //{
            //    throw new SPException("Ошибка использования директивы AGO или AIF. Метка в пределах макроса " + te.name + " не найдена.");
            //}
        }
Exemplo n.º 6
0
        /// <summary>
        /// Проверка макроса на IF-ELSE-ENDIF
        /// </summary>
        /// <param name="body"></param>
        public static void checkAIF(TMOEntity te)
        {
            List <SourceEntity> body = te.body;

            try
            {
                foreach (SourceEntity str in body)
                {
                    if (str.operation == "AIF")
                    {
                        if (str.operands.Count != 2)
                        {
                            throw new SPException("Некорректное использование директивы AIF: " + str.sourceString);
                        }
                        if (!String.IsNullOrEmpty(str.label))
                        {
                            throw new SPException("При директиве AIF метки быть не должно: " + str.sourceString);
                        }
                        if (!Utils.isLabel(str.operands[1]))
                        {
                            throw new SPException("При директиве AIF отсутствует метка для ссылки: " + str.sourceString);
                        }
                    }
                    if (str.operation == "AGO")
                    {
                        if (str.operands.Count != 1)
                        {
                            throw new SPException("Некорректное использование директивы AGO: " + str.sourceString);
                        }
                        if (!String.IsNullOrEmpty(str.label))
                        {
                            throw new SPException("При директиве AGO метки быть не должно: " + str.sourceString);
                        }
                        if (!Utils.isLabel(str.operands[0]))
                        {
                            throw new SPException("При директиве AGO отсутствует метка для ссылки: " + str.sourceString);
                        }
                    }
                }
            }
            catch (SPException ex)
            {
                throw new SPException(ex.Message, ex.errorString);
            }
            catch (Exception)
            {
                throw new SPException("Некорректное использование директив AIF-AGO");
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Проверка макроподстановки
        /// </summary>
        public static void checkMacroSubstitution(SourceEntity se, TMOEntity te)
        {
            if (se.operands.Count != te.parameters.Count)
            {
                throw new SPException("Некорректное количество параметров. Введено: " + se.operands.Count + ". Ожидается: " + te.parameters.Count);
            }
            //if (se.operands.Count != 0)
            //{
            //    throw new SPException("Вызов макроса не должен содержать параметров: " + se.sourceString);
            //}
            if (!String.IsNullOrEmpty(se.label))
            {
                throw new SPException("При макровызове макроса не должно быть меток: " + se.sourceString);
            }

            int temp; string[] vals = null;

            foreach (string prm in se.operands)
            {
                vals = prm.Split('=');
                if (vals.Length != 2)
                {
                    throw new SPException("Параметр '" + prm + "'. Параметры определены некорректно, разделители между '=', названием и значением параметра недопустимы.");
                }

                if (!Global.isInGlobal(vals[1]) && !Int32.TryParse(vals[1], out temp))
                {
                    throw new SPException("Параметр '" + vals[0] + "' имеет некорректное значение (" + vals[1] + ")");
                }
                if (Global.isInGlobal(vals[1]) && Global.searchInGlobal(vals[1]).value == null)
                {
                    throw new SPException("Параметр '" + vals[0] + "' - неинициализованная глобальная переменная");
                }
            }
            //if (!String.IsNullOrEmpty(se.label))
            //{
            //    throw new SPException("При макровызове макрса не должно быть меток: " + se.sourceString);
            //}
        }
Exemplo n.º 8
0
 /// <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) + ".");
     //}
 }
Exemplo n.º 9
0
        /// <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);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Достать предыдущий макрос (Вложенные макроопределния - да)
        /// </summary>
        /// <returns></returns>
        public static TMOEntity GetPrevNotFinishedMacro()
        {
            TMOEntity result = (from te in TMO.entities where !te.IsFinished select te).LastOrDefault();

            return(result);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Проверка макроса на IF-ELSE-ENDIF
        /// </summary>
        /// <param name="body"></param>
        public static void checkIF(TMOEntity te)
        {
            List <SourceEntity> body           = te.body;
            Stack <bool>        stackIfHasElse = new Stack <bool>();

            //проверка корректности IF-ELSE-ENDIF
            try
            {
                foreach (SourceEntity str in body)
                {
                    if (str.operation == "IF")
                    {
                        if (str.operands.Count != 1)
                        {
                            throw new SPException("Некорректное использование директивы IF: " + str.sourceString);
                        }
                        if (!String.IsNullOrEmpty(str.label))
                        {
                            throw new SPException("При директиве IF метки быть не должно: " + str.sourceString);
                        }
                        stackIfHasElse.Push(false);
                    }
                    if (str.operation == "ELSE")
                    {
                        if (str.operands.Count != 0)
                        {
                            throw new SPException("Некорректное использование директивы ELSE: " + str.sourceString);
                        }
                        if (!String.IsNullOrEmpty(str.label))
                        {
                            throw new SPException("При директиве ELSE метки быть не должно: " + str.sourceString);
                        }
                        if (stackIfHasElse.Peek() == true)
                        {
                            throw new SPException("Лишняя ветка ELSE: " + str.sourceString);
                        }
                        else
                        {
                            stackIfHasElse.Pop();
                            stackIfHasElse.Push(true);
                        }
                    }
                    if (str.operation == "ENDIF")
                    {
                        if (str.operands.Count != 0)
                        {
                            throw new SPException("Некорректное использование директивы ENDIF: " + str.sourceString);
                        }
                        if (!String.IsNullOrEmpty(str.label))
                        {
                            throw new SPException("При директиве ENDIF метки быть не должно: " + str.sourceString);
                        }
                        stackIfHasElse.Pop();
                    }
                }

                if (stackIfHasElse.Count > 0)
                {
                    throw new SPException("Отсутствует директива ENDIF");
                }
            }
            catch (SPException ex)
            {
                throw new SPException(ex.Message, ex.errorString);
            }
            catch (Exception)
            {
                throw new SPException("Некорректное использование директив IF - ENDIF");
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Проверка макроса на WHILE-ENDW
        /// </summary>
        public static void checkWhileEndw(TMOEntity te)
        {
            List <SourceEntity> body = te.body;
            int whileCount           = 0;

            //проверка корректности WHILE-ENDW
            try
            {
                foreach (SourceEntity str in body)
                {
                    if (str.operation == "WHILE")
                    {
                        if (str.operands.Count != 1)
                        {
                            throw new SPException("Некорректное количество операндов директивы WHILE: " + str.sourceString);
                        }
                        if (!String.IsNullOrEmpty(str.label))
                        {
                            throw new SPException("При директиве WHILE метки быть не должно: " + str.sourceString);
                        }
                        whileCount++;
                    }
                    else if (str.operation == "ENDW")
                    {
                        if (str.operands.Count != 0)
                        {
                            throw new SPException("Некорректное количество операндов директивы ENDW: " + str.sourceString);
                        }
                        if (!String.IsNullOrEmpty(str.label))
                        {
                            throw new SPException("При директиве ENDW метки быть не должно: " + str.sourceString);
                        }
                        whileCount--;
                        if (whileCount < 0)
                        {
                            throw new SPException("Некорректное использование директив WHILE и ENDW");
                        }
                    }
                    else if ((str.operation == "MACRO" || str.operation == "MEND") && whileCount > 0)
                    {
                        throw new SPException("Объявление макросов в цикле запрещено");
                    }
                    else if (str.operation == "GLOBAL" && whileCount > 0)
                    {
                        throw new SPException("Объявление глобальных переменных в цикле запрещено");
                    }
                }

                if (whileCount != 0)
                {
                    throw new SPException("Некорректное использование директив WHILE и ENDW");
                }
            }
            catch (SPException ex)
            {
                throw new SPException(ex.Message, ex.errorString);
            }
            catch (Exception)
            {
                throw new SPException("Некорректное использование директив WHILE и ENDW");
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Подстановка значений вместо параметров макроса
        /// </summary>
        /// <param name="te"></param>
        /// <param name="prms"></param>
        /// <returns></returns>
        public static List <SourceEntity> InvokeMacroParams(TMOEntity te, string[] prms)
        {
            // формируем локальную область видимости (параметры в виде key-value)
            Dictionary <string, int> dict = new Dictionary <string, int>();

            if (prms.Length != te.parameters.Count)
            {
                throw new SPException("Количество параметров вызова некорректно, необходимо " + te.parameters.Count + " параметров.");
            }
            string[] vals = null;
            int      temp;

            foreach (string prm in prms)
            {
                vals = prm.Split('=');
                if (vals.Length != 2)
                {
                    throw new SPException("Параметр '" + prm + "'. Параметры определены некорректно, разделители между '=', названием и значением параметра недопустимы.");
                }
                if (!te.parameters.Contains(vals[0]))
                {
                    throw new SPException("Параметра '" + vals[0] + "' не существует в макроопределении.");
                }
                if (!Global.isInGlobal(vals[1]) && !Int32.TryParse(vals[1], out temp))
                {
                    throw new SPException("Параметр '" + prm + "' имеет некорректное значение.");
                }
                if (Global.isInGlobal(vals[1]) && Global.searchInGlobal(vals[1]).value == null)
                {
                    throw new SPException("Параметр '" + prm + "' - неинициализованная глобальная переменная!");
                }
                if (dict.Keys.Contains(vals[0]))
                {
                    throw new SPException("Параметр '" + vals[0] + "' повторяется.");
                }

                dict.Add(vals[0], Global.isInGlobal(vals[1]) ? (int)Global.searchInGlobal(vals[1]).value : Int32.Parse(vals[1]));
            }

            List <SourceEntity> result = new List <SourceEntity>();

            foreach (SourceEntity se in te.body)
            {
                //Проверка на использование меток внутри макроса
                if (!String.IsNullOrEmpty(se.label) && se.operation != "MACRO")
                {
                    throw new SPException("Метки внутри макроса " + te.name + " запрещены");
                }
                result.Add(se.Clone());
            }

            // замена параметров в макросе на числа
            foreach (SourceEntity se in result)
            {
                if (se.operation == "WHILE")
                {
                    foreach (string sign in Utils.signs)
                    {
                        string[] t = se.operands[0].Split(new string[] { sign }, StringSplitOptions.None);
                        if (t.Length == 2)
                        {
                            if (te.parameters.Contains(t[0].Trim()))
                            {
                                t[0] = dict[t[0].Trim()].ToString();
                            }
                            if (te.parameters.Contains(t[1].Trim()))
                            {
                                t[1] = dict[t[1].Trim()].ToString();
                            }
                            se.operands[0] = t[0] + sign + t[1];
                            break;
                        }
                    }
                }
                else if (se.operation == "IF")
                {
                    foreach (string sign in Utils.signs)
                    {
                        string[] t = se.operands[0].Split(new string[] { sign }, StringSplitOptions.None);
                        if (t.Length == 2)
                        {
                            if (te.parameters.Contains(t[0].Trim()))
                            {
                                t[0] = dict[t[0].Trim()].ToString();
                            }
                            if (te.parameters.Contains(t[1].Trim()))
                            {
                                t[1] = dict[t[1].Trim()].ToString();
                            }
                            se.operands[0] = t[0] + sign + t[1];
                            break;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < se.operands.Count; i++)
                    {
                        if (dict.Keys.Contains(se.operands[i]))
                        {
                            se.operands[i] = dict[se.operands[i]].ToString();
                        }
                    }
                }
            }

            return(result);
        }