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(); }
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); }