Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            f           = new StreamWriter("output.txt", false);
            f.AutoFlush = true;

            grammar = new LL1Grammar("grammar.txt", false);  // создать грамматику
            if (grammar.valid)                               //проверить грамматику
            {
                LexReader lexs = new LexReader("input.txt"); //загрузить лексемы
                table = new Table();
                table.Build(grammar);                        //построить таблицу по грамматике
                if (ExecuteChecks(lexs, true))               //запуск проверки
                {
                    f.WriteLine("Ошибок не найдено");
                    REC.recalc();   //4 пересчет размеров структур
                    REC.save(f, 0); //4 вывод размеров структур
                }
                else
                {
                    f.WriteLine("Ошибка в позиции {0}", lexs.Positions[lexindex]);
                }
            }
            else
            {
                f.WriteLine("Обнаружена ошибка в описании грамматики");
            }
            Console.ReadKey();
        }
Ejemplo n.º 2
0
        static public bool ExecuteChecks(LexReader tk, bool DEB) // запуск проверки
        {
            int i            = 0;
            List <int> stack = new List <int>();
            string s;
            string name, redecl = "";
            List <List <string> > names = new List <List <string> >(); //** стек имен
            List <string> usertypes     = new List <string>();         //** пользовательские типы

            if (!C)
            {
                names.Add(new List <string>()); //**добавление первого уровня
            }
            int dim = 0;                        //, dim2 = 0;
            int mult = 1, size = 0;             //4  множитель и базовый размер типа
            bool addtolast = false;             //4  добавить новую запись или добавить имя к текущей

            stack.Add(-1);
            lexindex = 0;
            int minus = 1;

            name = tk.Lexems[lexindex];
            s    = name;
            TableItem T = table.AtIndex(i);

            while (true)
            {
                if (DEB)
                {
                    Console.Write("i={0} '{1}' [ ", i + 1, name);
                    for (int u = 0; u < stack.Count; u++)
                    {
                        Console.Write(",{0}", stack[u] + 1);
                    }
                    Console.Write("] ");
                    Console.Write(" {{ ", i + 1, name);
                    for (int u = 0; u < T.terms.Count; u++)
                    {
                        Console.Write("'{0}' ", T.terms[u]);
                    }
                    Console.WriteLine("} ");
                }
                bool b = false;
                for (int p = 0; p < T.terms.Count; p++)
                {
                    string term = T.terms[p];
                    if (term == name)
                    {
                        b = true; break;
                    }
                    if (term == "" && name == "{eof}")
                    {
                        b = true; break;
                    }
                    if (grammar.regterms.Contains(term) && !grammar.terminals.Contains(name))
                    {
                        int spec = grammar.regterms.IndexOf(term);
                        term = grammar.regvals[spec];
                        string tmp = term.Substring(1, term.Length - 2);
                        b = Regex.IsMatch(name, tmp);
                        if (b)
                        {
                            break;
                        }
                    }
                }
                if (b)
                {
                    if (T.action.Length > 0) //** обработка действий
                    {
                        string act = T.action;
                        if (DEB)
                        {
                            Console.WriteLine("act {0}({1})\n", act, s);
                        }
                        if (act.ToUpper() == "<NEWVAR>") // новая переменная
                        {
                            if (s.Length > 8)
                            {
                                s = s.Substring(0, 8);
                            }
                            if (names[names.Count - 1].Contains(s))
                            {
                                break; // есть на этом уровне
                            }
                            if (usertypes.LastOrDefault() == s)
                            {
                                break; //есть в пользовательских
                            }
                            names[names.Count - 1].Add(s);
                            REC.addname(s, names.Count, addtolast); //4 добавить имя
                            addtolast = false;                      //4 сбросить флаг нового имени
                        }
                        if (act.ToUpper() == "<NEWTYPE>")           // новый тип
                        {
                            if (usertypes.LastOrDefault() == s)
                            {
                                break;
                            }
                            if (names.Count >= 2)
                            {
                                if (names[names.Count - 2].Contains(s))
                                {
                                    break; // есть на этом уровне
                                }
                            }
                            //if (usertypes.Contains(s)) break;//есть в пользовательских
                            usertypes.Add(s);
                        }
                        if (act.ToUpper() == "<STRUCTIN>")   //вход в запись
                        {
                            names.Add(new List <string>());  // новый уровень
                        }
                        if (act.ToUpper() == "<STRUCTOUT>")  //выход
                        {
                            names.RemoveAt(names.Count - 1); // удалить 1 уровень
                        }
                        if (act.ToUpper() == "<STARTCALC>")
                        {
                            size = 0;
                            mult = 1;
                        }
                        if (act.ToUpper() == "<ADDNAME>") // новое имя через запятую в том же описании ( a,b:... )
                        {
                            addtolast = true;
                        }

                        if (act.ToUpper() == "<UPDSIZE>")          //4 сохранить подсчитанный размер
                        {
                            REC.setsize(size * mult, names.Count); // размер * множитель , глубина вложенности
                        }
                        if (act.ToUpper() == "<1>")                //4 размер 1 байт
                        {
                            size = 1;
                        }
                        if (act == "<2>") //4 размер 2 байт
                        {
                            size = 2;
                        }
                        if (act == "<4>") //4 размер 4 байт
                        {
                            size = 4;
                        }
                        if (act == "<6>") //4 размер 6 байт
                        {
                            size = 6;
                        }
                        if (act == "<8>") //4 размер 8 байт
                        {
                            size = 8;
                        }
                        if (act == "<10>") //4 размер 8 байт
                        {
                            size = 10;
                        }
                        if (act == "<256>") // 4 строка 256 (может перезаписаться)
                        {
                            size = 256;
                        }
                        if (act.ToUpper() == "<MULT2>") //4 добавить множитель 2. размерность массива
                        {
                            mult *= 2;
                        }
                        if (act.ToUpper() == "<MULT256>") //4 *256
                        {
                            mult *= 256;
                        }
                        if (act.ToUpper() == "<MULT65535>") //4 *2 байт
                        {
                            mult *= 65535;
                        }


                        if (act.ToUpper() == "<C256>") //проверка длины строки
                        {
                            int sz;
                            sz = s2int(s);
                            if (sz < 1 || sz > 255)
                            {
                                break;
                            }
                            size = sz + 1;//4 обновление размера для строки
                        }
                        if (act.ToUpper() == "<MINUS>")
                        {
                            minus = -1;
                        }

                        if (act.ToUpper() == "<DIM>")
                        {
                            dim = s2int(s) * minus; // сохранить первую размерность массива
                            if (dim <= 0)
                            {
                                break;           //диапазон не правильный
                            }
                            mult *= dim;
                            minus = 1;
                        }

                        /*
                         * if (act == "<DIM2>") // вторая размерность
                         * {
                         *  dim2 = s2int(s) * minus;
                         *  if (dim1 > dim2) break;
                         *  mult *= dim2 - dim1 + 1; //4 обновление множителя для диапазона
                         *  minus = 1;
                         * }*/
                    } //** обработка действий


                    if (T.accept)
                    {
                        lexindex++;
                        name = lexindex < tk.Lexems.Count ? tk.Lexems[lexindex] : "";
                        s    = name;
                        if (DEB)
                        {
                            Console.WriteLine("read '{0}'\n", name);
                        }
                        //				chvar=false;
                    }
                    if (T.stack)
                    {
                        stack.Add(i);
                    }
                    if (T.Return)
                    {
                        if (stack.Count == 0)
                        {
                            break;
                        }
                        i = stack[stack.Count - 1];
                        stack.RemoveAt(stack.Count - 1);
                        if (i == -1)
                        {
                            break;
                        }
                        i++;
                        T = table.AtIndex(i);
                        continue;
                    }
                    if (T.jump != -1)
                    {
                        i = T.jump;
                        T = table.AtIndex(i);
                        continue;
                    }
                    ;
                }
                else
                {
                    if (!T.error)
                    {
                        i++;
                        T = table.AtIndex(i);
                        continue;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(stack.Count == 0);
        }