private void action(int index, string val) //** задать связанное действие { TableItem t = Tbl[index]; t.action = val; Tbl[index] = t; }
private void accept(int index, bool val) // задать завершение { TableItem t = Tbl[index]; t.accept = val; Tbl[index] = t; }
private void error(int index, bool val) //задать ошибку { TableItem t = Tbl[index]; t.error = val; Tbl[index] = t; }
private void Return(int from, bool val) // задать возврат { TableItem t = Tbl[from]; t.Return = val; Tbl[from] = t; }
private void stack(int from, bool val) // задать помещение в стек { TableItem t = Tbl[from]; t.stack = val; Tbl[from] = t; }
private void jump(int from, int to) // задать переход в элемент таблицы { TableItem t = Tbl[from]; t.jump = to; Tbl[from] = t; }
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); }
public void Build(LL1Grammar Gr) // построить таблицу по грамматике { List <Rule> Rules = Gr.Grammar; List <int> ml = new List <int>(); List <int> mr = new List <int>(); string st = ""; int k = 0, t = 0; int i = 0; while (i < Rules.Count) { st = Rules[i].rname; for (int j = i; j < Rules.Count; j++) { if (Rules[i].rname != Rules[j].rname) { break; } Tbl.Add(new TableItem(Rules[j].rname, "")); if (i == j) { k = Tbl.Count - 1; } Program.listmergenew(Tbl[Tbl.Count - 1].terms, Rules[j].termchars); ml.Add(Tbl.Count - 1); t = j - i + 1; if (j > i) { error(Tbl.Count - 2, false); } } for (int j = i; j < i + t; j++) { if (Rules[i].rname != Rules[j].rname) { break; } for (int p = 0; p < Rules[j].rightnames.Count; p++) { TableItem tt = new TableItem(Rules[i].rname, Rules[j].rightnames[p]); Tbl.Add(tt); if (p == 0) { jump(k + j - i, Tbl.Count - 1); } if (Gr.IsRuleName(Rules[j].rightnames[p])) { for (int ttt = 0; ttt < Rules.Count; ttt++) { if (Rules[ttt].rname == Rules[j].rightnames[p]) { Program.listmergenew(Tbl[Tbl.Count - 1].terms, Rules[ttt].termchars); } } stack(Tbl.Count - 1, p < Rules[j].rightnames.Count - 1); } else if ((Rules[j].rightnames[p] != "E")) { Program.listaddnew(Tbl[Tbl.Count - 1].terms, Rules[j].rightnames[p]); accept(Tbl.Count - 1, true); Return(Tbl.Count - 1, p == Rules[j].rightnames.Count - 1); action(Tbl.Count - 1, Rules[j].action[p]); //** переписать действие в таблицу } else { Rules[j].rightnames[p] = "E"; Program.listmergenew(Tbl[Tbl.Count - 1].terms, Rules[j].termchars); Return(Tbl.Count - 1, p == Rules[j].rightnames.Count - 1); } } mr.Add(Tbl.Count - 1); } while (i < Rules.Count && st == Rules[i].rname) { i++; } } for (i = 0; i < Tbl.Count; i++) { bool b = false; for (int j = 0; j < ml.Count; j++) { if (ml[j] == i) { b = true; } } if (Gr.IsRuleName(Tbl[i]._s2) && !b) // из прав части { for (int j = 0; j < Tbl.Count; j++) { if (Tbl[j]._s1 == Tbl[i]._s2 && Tbl[j]._s2 == "") { jump(i, j); break; } } } b = false; for (int j = 0; j < mr.Count; j++) { if (mr[j] == i) { b = true; } } if (!Gr.IsRuleName(Tbl[i]._s2) && Tbl[i]._s2 != "") // из прав части { if (b) { jump(i, -1); } else { jump(i, i + 1); } } } }