Exemple #1
0
        //****************************************************************************************************
		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("Синтаксическая ошибка в выражении");
			}
		}
Exemple #2
0
        //****************************************************************************************************
		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));
			}
		}