//**************************************************************************************************** private void Analyse(Parser p) { try { LinkedList l = new LinkedList(); while (p.MoveNext()) l.Add(p.Current); OPZ(l); } catch (CalcException ex) { throw ex; } catch { throw new SyntaxErrorException("Синтаксическая ошибка в выражении"); } }
//**************************************************************************************************** private void OPZ(LinkedList tokens) { /* ** Бинарная операция выталкивает из стека в результат * все операции с большим или равным приоритетом, затем * записывается в стек сама * ** Унарная операция записывается в стек * ** Открывающая скобка записывается в стек * ** Закрывающая скобка выталкивает в результат все операции * из стека до открывающей скобки, затем * скобки уничтожаются и выталкиваются унарные операции * ** Переменная или константа сразу пишутся в результат, затем * выталкиваются из стека унарные операции * ** При вызове функции * сначала отдельно разбираются все операнды, затем в результат * дописывается сама функция, как операция * ** Обращение к элементу массива обрабатывается аналогично * В конце все оставшиеся в стеке операции выталкиваются в результат */ InterprEnvironment env = InterprEnvironment.Instance; if (tokens.IsEmpty()) return; LinkedList.Iterator itr = tokens.GetIterator(); LinkedList stk = new LinkedList(); while (itr.HasMore) { string si = (itr.Step() as System.String); if (si == "(") { stk.Add(O_BR); } else if (si == ")") { while (true) { object o = stk.RemoveLast(); if (o == O_BR) break; AddFront(new Call(o as Operation)); } while ((!stk.IsEmpty()) && IsUnary(stk.Last)) { AddFront(new Call(stk.RemoveLast() as Operation)); } } else if (Parser.IsID(si)) { bool bfun = false; bool barray = false; if (itr.HasMore) { string s = (itr.Step() as System.String); if (s == "[") bfun = true; else if (s == "{") barray = true; else itr.Previous(); } if (bfun) { LinkedList l = null; while (true) { l = new LinkedList(); int level = 0; while (true) { if (!itr.HasMore) throw new SyntaxErrorException("Синтаксическая ошибка в выражении"); string sj = (itr.Step() as System.String); if (sj == "[") { level++; l.Add(sj); } else if (sj == "]") { if (level == 0) goto label1; else { level--; l.Add(sj); } } else if (sj == ",") { if (level > 0) l.Add(sj); else break; } else l.Add(sj); } OPZ(l); } label1: if (l != null) OPZ(l); Operation sub = env.GetFunction(si); AddFront(new Call(sub)); while ((stk.Count > 0) && IsUnary(stk.Last)) { AddFront(new Call((Operation) stk.RemoveLast())); } } else if (barray) { LinkedList l = new LinkedList(); int level = 0; while (true) { if (!itr.HasMore) throw new SyntaxErrorException("Синтаксическая ошибка в выражении"); String sj = (String) itr.Step(); if (sj == "{") { level++; l.Add(sj); } else if (sj == "}") { if (level == 0) break; else { level--; l.Add(sj); } } else l.Add(sj); } OPZ(l); VarName v = new VarName(si); AddFront(v); AddFront(new Call(Operation.INDEX)); while ((stk.Count > 0) && IsUnary(stk.Last)) { AddFront(new Call(stk.RemoveLast() as Operation)); } } else { VarName v = new VarName(si); AddFront(v); while ((stk.Count > 0) && IsUnary(stk.Last)) { AddFront(new Call(stk.RemoveLast() as Operation)); } } } else { Operation op = StrToOperation(si); if (op == null) { SingleVar sv = SingleVar.FromString(si); if (si == null) throw new SyntaxErrorException("Синтаксическая ошибка в выражении"); AddFront(sv); while ((stk.Count > 0) && IsUnary(stk.Last)) { AddFront(new Call(stk.RemoveLast() as Operation)); } } else { //operation if (op == Operation.ADD) { itr.Previous(); if (!itr.HasPrevious) { stk.Add(Operation.UPLUS); itr.Step(); continue; } String strpr = (String) itr.Previous(); itr.Step(); itr.Step(); if ((StrToOperation(strpr) != null) || (strpr == "(") || (strpr == "[") || (strpr == "{")) { stk.Add(Operation.UPLUS); continue; } } else if (op == Operation.SUB) { itr.Previous(); if (!itr.HasPrevious) { stk.Add(Operation.UMINUS); itr.Step(); continue; } String strpr = (String) itr.Previous(); itr.Step(); itr.Step(); if ((StrToOperation(strpr) != null) || (strpr == "(") || (strpr == "[") || (strpr == "{")) { stk.Add(Operation.UMINUS); continue; } } else if (op == Operation.NOT) { stk.Add(op); continue; } if (stk.IsEmpty() || (stk.Last == O_BR)) { stk.Add(op); } else { int pr = Priority(op); while (true) { if (stk.IsEmpty()) break; Object stktop = stk.Last; if (stktop is Operation) { int pr1 = Priority(stktop as Operation); if ((pr <= pr1) && (pr1 < 6)) { AddFront(new Call(stktop as Operation)); stk.RemoveLast(); } else break; } else break; } stk.Add(op); } } } } while (!stk.IsEmpty()) { Object o = stk.RemoveLast(); AddFront(new Call(o as Operation)); } }