/// <summary> /// Синтаксический анализирует выражение состоящее из отдельных слов /// </summary> /// <param name="expression"></param> /// <returns>Возвращает последовательность идентификаторов и операторов</returns> public static List <ILexem> ToLexems(List <string> expression) { List <ILexem> result = new List <ILexem>(); EvalObject temp; for (int i = 0; i < expression.Count(); i++) { if (Operators.ContainsKey(expression[i])) { result.Add(Operators[expression[i]]); } else if (Service.ContainsKey(expression[i])) { result.Add(Service[expression[i]]); } else { temp = Memory.CreateObjectFromValue(expression[i]); if (temp != null) { result.Add(new Identifier(temp)); } else { result.Add(IdentifierManager.ReferrenceIdentifier(expression[i])); } } } return(result); }
/// <summary> /// Выполняет постфиксную запись лексем /// </summary> /// <param name="Postfix"></param> /// <returns></returns> static public Identifier Evaluate(List <ILexem> Postfix) { Stack <ILexem> buffer = new Stack <ILexem>(); foreach (var item in Postfix) { if (item.Type == LexemType.Identifier || item.Type == LexemType.Constant) { buffer.Push(item); } else { // получаю функцию, взаимодействующую с операторами ICallable func; if (item.Type == LexemType.Operator) { func = (Operator)item; } else { func = (Function)item; } // достаю параметры функции List <Identifier> parameters = new List <Identifier>(); for (int i = 0; i < func.ParamCount - 1; i++) { parameters.Add((Identifier)buffer.Pop()); } Identifier op1 = (Identifier)buffer.Pop(); if (op1.Value == null && item.Literal != "=") { throw new VariableException(op1.Literal, "Not assigned, but referenced"); } if (parameters.Any((lex) => lex.Address == null)) { throw new VariableException("Not assigned, but referenced"); } // выполняю вычисление EvalObject result = func.Evaluate(ref op1, parameters.ToArray()); buffer.Push(new Identifier(result)); } } var res = (Identifier)buffer.Pop(); IdentifierManager.Refresh(ref res); return(res); }