示例#1
0
        void codeProgram()
        {
            Console.WriteLine(".CODE");
            Console.WriteLine("MAIN PROC");
            Console.WriteLine("FINIT");
            fOut.WriteLine(".CODE");
            fOut.WriteLine("MAIN PROC");
            fOut.WriteLine("FINIT");
            for (int i = 0; i < OPZ.Length; i++)
            {
                Console.WriteLine("\n; Выражение " + i);
                fOut.WriteLine("\n; Выражение " + i);
                Console.WriteLine("; Начало выражения");
                fOut.WriteLine("; Начало выражения");
                string[]       OPZ_i     = OPZ[i].Split(" ");
                Stack <string> OPZ_stack = new Stack <string>();
                for (int j = 0; j < OPZ_i.Length; j++)
                {
                    // Если ОПЗ_i - операция
                    if (Operations.SearchIsExist(OPZ_i[j]))
                    {
                        string[] operands = { OPZ_stack.Pop(), OPZ_stack.Pop() };
                        OPZ_i[j] = processingOperation(OPZ_i[j], operands);
                    }



                    OPZ_stack.Push(OPZ_i[j]);
                }
                Console.WriteLine("; Конец выражения\n");
                fOut.WriteLine("; Конец выражения\n");
            }


            Console.WriteLine("END MAIN");
            fOut.WriteLine("END MAIN");
        }
        public void WorkSyntAn()
        {
            // Чтение всех токенов (как целый текст)
            if (tokensAll.Length > 1)
            {
                tokensAll = tokensAll.Remove(tokensAll.Length - 1).Replace("\r", "");                    //.Replace("\n", "");
            }
            string[] tokens = { };
            // Чтение токенов в массив, по одному в элементе
            if (tokensAll.Length > 1)
            {
                tokens = tokensAll.Remove(tokensAll.Length - 1).Split('|', '\n');
            }


            int[] token;               // Хранит два числа: первое - номер таблицы, второе - номер элемента в таблице

            bool start = false;        // Было ли начало программы
            bool end   = false;        // Была ли окончена программа
            bool init  = false;        // Инизиализация
                                       //bool assignment = false;
            bool oper         = false; // Оператор
            bool type         = false; // Обьявление типа
            bool d_type       = false; // повторное Обьявление типа
            bool ID           = false; // Обьявление идентификатора
            bool isSemiNeeded = false; // отсутствует ли ";"?
            bool enumeration  = false; // Перечисление
            bool init_end     = false;
            bool oper_end     = false;

            Stack <int[]> opers = new Stack <int[]>(); // стэк операций

            string type_s = "";                        // тип

            string id = "";                            // идентификатор

            int[] idtoken = { };                       // идентификатор

            int line = 1;                              // номер строки

            for (int numToken = 0; numToken < tokens.Length; numToken++)
            {
                if (tokens[numToken] == "") // Если нет токена
                {
                    line++;
                    f1.WriteLine();
                    continue; // Переходим к следующему токену
                }

                string token_s = GetToken(token = ReadToken(tokens, numToken)); // Определяем имя токена

                if (end)
                {
                    WriteError(line, "После конца программы");
                    break;
                }

                if (token_s == "void main(){")  // Если начало функции
                {
                    start = true;
                    continue; // Переходим к следующему токену
                }

                if (token_s == "}") // Если конец программы
                {
                    end = true;
                    break;  // Конец синтаксического анализа
                }

                if (!start) // Если есть символы перед начальным токеном
                {
                    WriteError(line, "Неверное начало программы");
                    continue; // Ищем начало программы
                }

                if (start) // Программа была начата
                {
                    if (token_s == "void main(){")
                    {
                        WriteError(line, "Повторное обьявление программы");
                        continue; // Переходим к следующему символу
                    }


                    if (KeyWords.SearchIsExist(token_s)) // Токен - тип?
                    {
                        if (init)
                        {
                            d_type = true;
                        }
                        init = true; // Переходим к инициализации

                        if (isSemiNeeded)
                        {
                            WriteError(line - 1, "Требуется \";\"");
                        }
                    }

                    if (init && d_type || oper && init)
                    {
                        WriteError(line - 1, "Требуется \";\"");
                        isSemiNeeded = true;
                        init_end     = true;
                        oper_end     = true;
                    }

                    if (token_s == ";" && token[0] == 1 || isSemiNeeded) // конец строки
                    {
                        if (!init_end && init)
                        {
                            WriteError(line, "Требуется идентификатор");
                        }

                        if (!oper_end && oper)
                        {
                            WriteError(line, "Требуется идентификатор или константа");
                        }
                        init         = false;
                        init_end     = false;
                        type         = false;
                        ID           = false;
                        isSemiNeeded = false;
                        oper         = false;
                        enumeration  = false;

                        while (pop_operations(opers) == 0)
                        {
                            ;                           // Вывод стека операций
                        }
                        if (pop_operations(opers) == 2) // Если найдена открывающаяся скобка
                        {
                            WriteError(line, "Ожидается закрывающаяся скобочка");
                            opers.Pop();
                        }
                        while (pop_operations(opers) == 0)
                        {
                            ;                          // Вывод стека операций
                        }
                        //Console.WriteLine();
                        if (!d_type)
                        {
                            continue;
                        }
                    }


                    if (init || d_type) // line
                    {
                        if (d_type)
                        {
                            d_type = false;
                            init   = true;
                        }
                        // Если при инициализации были заполнены и идентификатор и тип
                        if (ID && type)                         // var asd /////// по идее без type,
                                                                // т.к. {var asd = 1} и {asd = 1} -> {TYPE ID = CONST} и {ID = CONST}
                        {
                            if (token_s == "=" && !enumeration) // ожидание оператора
                            {
                                oper     = true;
                                type     = false;
                                init_end = true;

                                //init = false;
                            }
                            else
                            {
                                if (token_s == ",") // ожидание перечисления
                                {
                                    enumeration = true;
                                    ID          = false;
                                    init_end    = false;
                                    continue;
                                }
                                else
                                {
                                    WriteError(line, "Неожиданный символ \"" + token_s + "\""); // ошибка
                                    continue;
                                }
                            }
                        }

                        if (enumeration || type)
                        {
                            if (Constants.SearchIsExist(token_s))
                            {
                                WriteError(line, "Присвоение константе типа");
                                continue;
                            }
                            ID       = true;
                            id       = token_s;
                            init_end = true;
                            idtoken  = token;
                            if (!Identificators.SetType(id, type_s))
                            {
                                WriteError(line, "Повторная инициализация \"" + token_s + "\""); // ошибка
                            }
                        }

                        if (!type)
                        {
                            type   = true;
                            type_s = token_s;
                        }
                    }

                    if (!init && !oper)
                    {
                        if (ID)
                        {
                            if (token_s == "=")
                            {
                                oper = true;
                                //ID = false;
                                init = true;
                            }
                            else
                            {
                                WriteError(line, "Неожиданный символ\"" + token_s + "\"");
                            }
                        }

                        if (Identificators.SearchIsExist(token_s) && !ID)
                        {
                            if (Constants.SearchIsExist(token_s))
                            {
                                WriteError(line, "Присвоение константе типа");
                                continue;
                            }
                            ID      = true;
                            id      = token_s;
                            idtoken = token;
                        }
                    }

                    if (oper)
                    {
                        if (init) // Если прошла инициализация
                        {
                            WritePostfix(idtoken, opers);
                            init = false;
                            Identificators.SetValue(id, true);
                            //isSemiNeeded = false;
                        }

                        if (ID && (Operations.SearchIsExist(token_s) || Divisions.SearchIsExist(token_s)) || !ID)
                        {
                            ID       = false;
                            oper_end = false;
                            int error_in_oper = WritePostfix(token, opers);

                            if (error_in_oper == 4)
                            {
                                WriteError(line, "Использование переменной без значения\"" + token_s + "\"");
                            }
                            if (error_in_oper == 1)
                            {
                                WriteError(line, "Использование неинициализированной переменной \"" + token_s + "\"");
                            }

                            if (error_in_oper == 2)
                            {
                                WriteError(line, "Не найдена открывающаяся скобка");
                            }

                            if (error_in_oper == 3 || error_in_oper == 1)
                            {
                                ID       = true;
                                oper_end = true;
                            }
                        }
                        else
                        {
                            WriteError(line, "Ожидается знак операции или скобка");
                            continue;
                        }
                    }
                }
            }
            if (!end)
            {
                WriteError(line, "Требуется \"}\"");
            }
            f1.Close();
            f.Close();
        }
        public List <int[]> FiniteStateMachine(string line)
        {
            Statuses Status = Statuses.Start;

            char[]       letters       = line.ToCharArray();
            string       name          = "";
            bool         flag_constant = false;
            List <int[]> Tokens        = new List <int[]>();
            char         openchar      = ' ';
            bool         wasPoint      = false;

            //bool flag_comment = false;
            bool flagLineComment = false;

            foreach (char letter in letters)
            {
                if (Status == Statuses.End && letter != '\n')
                {
                    Status = Statuses.Start;
                }

                if (Status == Statuses.ReadChar)
                {
                    if ("\'\"".Contains(letter) && (name != "\'\\" || name != "\"\\"))
                    {
                        if (name.Length == 1 && letter == '\'')
                        {
                            Status = Statuses.Error;
                        }
                        else
                        {
                            if (letter == openchar && (name.Length <= 2 || name.Length == 3 && name[1] != '\\'))
                            {
                                typeconst = "char";
                                name     += letter;
                                Status    = Statuses.End;
                            }
                            else
                            {
                                Status = Statuses.Error;
                            }
                        }
                    }
                    else
                    {
                        name += letter;
                    }
                }
                if (Status == Statuses.Start)
                {
                    if (flagBlockComment)
                    {
                        Status = Statuses.ReadComment;
                    }
                    else
                    {
                        openchar      = ' ';
                        name          = "";
                        flag_constant = false;
                        wasPoint      = false;
                        //flag_comment = false;
                        flagLineComment = false;
                        if ("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_".Contains(letter))
                        {
                            Status = Statuses.ReadName;
                        }
                        else if ("1234567890.".Contains(letter))
                        {
                            flag_constant = true;

                            Status = Statuses.ReadNum;
                        }
                        else if (letter == '\'' || letter == '\"')
                        {
                            flag_constant = true;
                            Status        = Statuses.ReadChar;
                            openchar      = letter;
                            name         += letter;
                        }
                        else if (letter == ';' || letter == ',' || letter == '(' || letter == ')' || letter == '}')
                        {
                            name   = letter.ToString();
                            Status = Statuses.End;
                        }
                        else if (Operations.SearchIsExist(letter.ToString()) || letter == '!' || letter == '=')
                        {
                            Status = Statuses.ReadOperator;
                        }
                        else if (letter == '/')
                        {
                            Status = Statuses.ReadComment;
                        }
                        else if (letter == '\n')
                        {
                            Status = Statuses.End;
                        }
                    }
                }
                if (Status == Statuses.ReadName)
                {
                    if (letter != ';' && letter != ' ' && letter != ',' && letter != '\n' || name == "void")
                    {
                        if ("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_".Contains(letter) || "1234567890".Contains(letter) || name == "void" && letter == ' ' ||
                            name == "void main" && letter == '(' || name == "void main(" && letter == ')' ||
                            name == "void main()" && letter == '{')
                        {
                            name += letter;
                        }
                        else
                        {
                            Status = Statuses.Error;
                        }
                    }
                    else
                    {
                        Status = Statuses.End;
                    }
                }

                if (Status == Statuses.ReadNum)
                {
                    if ("1234567890.".Contains(letter))
                    {
                        if (name == "0" && letter != '.')
                        {
                            name = "";
                        }
                        Status = Statuses.ReadNum;
                        name  += letter;
                        if (letter == '.')
                        {
                            if (wasPoint)
                            {
                                Status = Statuses.Error;
                            }
                            else
                            {
                                wasPoint = true;
                            }
                        }
                    }
                    else if (letter == ';' || letter == ' ' || letter == '\n')
                    {
                        if (name == ".")
                        {
                            Status = Statuses.Error;
                        }
                        else
                        {
                            if (wasPoint)
                            {
                                typeconst = "float";
                            }
                            else
                            {
                                typeconst = "int";
                            }
                            Status = Statuses.End;
                        }
                    }
                    else
                    {
                        Status = Statuses.Error;
                    }
                }

                if (Status == Statuses.ReadComment)
                {
                    if (comment == "/")
                    {
                        if (letter == '/')
                        {
                            flagLineComment = true;
                        }
                        else if (letter == '*')
                        {
                            flagBlockComment = true;
                        }
                        else
                        {
                            Status = Statuses.Error;
                        }
                    }
                    else if (flagLineComment && letter == '\n')
                    {
                        Status          = Statuses.End;
                        flagLineComment = false;
                        comment         = "";
                    }
                    else if (flagBlockComment && comment[^ 2] == '*' && comment[^ 1] == '/' && comment.Length > 3)
                    {
                        flagBlockComment = false;
                        Status           = Statuses.Start;
                        comment          = "";
                    }
                    if (letter == '\n' || (!flagBlockComment && !flagLineComment) && letter == ' ')
                    {
                        Status = Statuses.End;
                    }
                    else
                    {
                        comment += letter;
                    }
                }

                if (Status == Statuses.ReadOperator)
                {
                    name += letter;
                    if (name == "==")
                    {
                        Status = Statuses.End;
                    }
                    else
                    {
                        if (name[0] != '!' && name[0] != '=' && name.Length == 1)
                        {
                            Status = Statuses.End;
                        }
                        else
                        if (name.Length == 2)
                        {
                            if (name == "!=")
                            {
                                Status = Statuses.End;
                            }
                            else if (name == "= ")
                            {
                                Status = Statuses.End;
                                name   = "=";
                            }
                            else
                            {
                                Status = Statuses.Error;
                            }
                        }
                    }
                }

                if (Status == Statuses.End)
                {
                    if (!flagBlockComment && !flagLineComment)
                    {
                        if (letter != '\n' || name.Length > 0)
                        {
                            int[] token = GetToken(name, flag_constant);
                            flag_constant = false;
                            if (token[1] != -1)
                            {
                                Tokens.Add(token);
                                if ((letter == ';' || letter == ',') && name != letter.ToString())
                                {
                                    Tokens.Add(GetToken(letter.ToString(), flag_constant));
                                }
                                name = "";
                            }
                        }
                    }
                }
            }

            if (Status != Statuses.End)
            {
                Console.WriteLine("ERROR");
                comment = "";
            }


            return(Tokens);
        }