private void OnClosingBracket() { var funcNode = new MultiTreeNode <Value>(new Value(ValueType.Function, null)); while (OperationsStack.Peek() != "(") { if (EvalOperator() == ",") { funcNode.AddChild(OperandsStack.Pop()); } } OperationsStack.Pop(); if (OperationsStack.Count > 0 && Library.IsFunction(OperationsStack.Peek())) { funcNode.Data.Val = OperationsStack.Pop(); OperandsStack.Push(funcNode); return; } if (funcNode.Count > 0) { funcNode.Data.Val = "MkTuple"; OperandsStack.Push(funcNode); } }
private void OnClosingSquareBracket() { var funcNode = new MultiTreeNode <Value>(new Value(ValueType.Function, null)); while (OperationsStack.Peek() != "[") { if (EvalOperator() == ",") { funcNode.AddChild(OperandsStack.Pop()); } } OperationsStack.Pop(); if (OperationsStack.Count > 0 && OperationsStack.Peek() == "MkList") { funcNode.Data.Val = OperationsStack.Pop(); OperandsStack.Push(funcNode); return; } if (OperationsStack.Count > 0 && OperationsStack.Peek() == "ByIdx") { funcNode.Data.Val = OperationsStack.Pop(); funcNode.AddChild(OperandsStack.Pop()); funcNode.AddChild(OperandsStack.Pop()); OperandsStack.Push(funcNode); return; } }
private void OnFunction(TokenLine.TokenEnum token) { if (token.PeekNext() == "(") { OperationsStack.Push(token.Current); OperationsStack.Push("("); token.MoveNext(); if (token.PeekNext() != ")") { OperationsStack.Push(","); } } else { OperandsStack.Push(new MultiTreeNode <Value>(new Value(ValueType.Variable, token.Current))); } }
private void ParseToken(TokenLine.TokenEnum token) { if (Library.IsFunction(token.Current)) { OnFunction(token); } else if (token.Current == "[") { OnOpeningSquareBracket(token); } else if (RouteOperators.Contains(token.Current)) { OperationsStack.Push(token.Current); } else if (token.Current == ")") { OnClosingBracket(); } else if (token.Current == "]") { OnClosingSquareBracket(); } else if (Library.IsOperator(token.Current)) { while (OperationsStack.Count > 0 && Library.Operators[OperationsStack.Peek()] >= Library.Operators[token.Current]) { EvalOperator(); } OperationsStack.Push(token.Current); } else { var value = Translator.ParseTypes(token.Current); OperandsStack.Push(value == null ? new MultiTreeNode <Value>(new Value(ValueType.Variable, token.Current)) : new MultiTreeNode <Value>(new Value(ValueType.Value, value))); } }
private void OnOpeningSquareBracket(TokenLine.TokenEnum token) { if (token.PeekPrev() == null || token.PeekPrev() == "(" || token.PeekPrev() == "[" || Library.Operators.ContainsKey(token.PeekPrev())) { OperationsStack.Push("MkList"); OperationsStack.Push("["); if (token.PeekNext() != "]") { OperationsStack.Push(","); } } else { OperationsStack.Push("ByIdx"); OperationsStack.Push("["); } }
public MultiTreeNode <Value> ParseLine(string line) { var currentToken = new TokenLine(line).GetEnumerator(); while (currentToken.MoveNext()) { ParseToken(currentToken); } while (OperationsStack.Count != 0) { EvalOperator(); } var result = OperandsStack.Pop(); OperationsStack.Clear(); OperandsStack.Clear(); return(result); }
private string EvalOperator() { var op = OperationsStack.Pop(); if (op == ",") { return(op); } if (!Library.Operators.ContainsKey(op)) { throw new ArgumentException($"Expected operator, but was <{op}>"); } var opNode = new MultiTreeNode <Value>(new Value(ValueType.Function, op)); opNode.AddChild(OperandsStack.Pop()); opNode.AddChild(OperandsStack.Pop()); OperandsStack.Push(opNode); return(op); }
/// <summary> /// Returns a compiled expression for specified source string. /// </summary> public CompiledExpression Compile(PreparedExpression preparedExpression) { if (preparedExpression == null) { throw new ArgumentNullException("preparedExpression"); } // OperationsStack operationsStack = new OperationsStack(operationsRegistry); // for (int itemIndex = 0; itemIndex < preparedExpression.PreparedExpressionItems.Count; itemIndex++) { PreparedExpressionItem item = preparedExpression.PreparedExpressionItems[itemIndex]; // If constant or variable - add to result if (item.Kind == PreparedExpressionItemKind.Constant) { operationsStack.PushConstant(item.Constant); } if (item.Kind == PreparedExpressionItemKind.Variable) { operationsStack.PushVariable(item.VariableName); } // If delimiter if (item.Kind == PreparedExpressionItemKind.Delimiter) { operationsStack.PushDelimiter(item.DelimiterKind); } // Signature (operator signature / part of signature / function) if (item.Kind == PreparedExpressionItemKind.Signature) { List <Operation> operations = new List <Operation>(operationsRegistry.GetOperationsUsingSignature(item.Signature)); operations.Sort(new Comparison <Operation>(compareOperationsByOperandsCount)); // for (int i = 0; i < operations.Count; i++) { Operation operation = operations[i]; // Operator if (operation.Kind == OperationKind.Operator) { // Unary operator if (operation.OperandsCount == 1) { // If operator placed at the start of subexpression if ((itemIndex == 0) || ((itemIndex > 0) && (preparedExpression.PreparedExpressionItems[itemIndex - 1].Kind == PreparedExpressionItemKind.Delimiter) && (preparedExpression.PreparedExpressionItems[itemIndex - 1].DelimiterKind == DelimiterKind.OpeningBrace) || (preparedExpression.PreparedExpressionItems[itemIndex - 1].DelimiterKind == DelimiterKind.Comma))) { // operationsStack.PushUnaryOperator(operation); break; } } // Binary operator if (operation.OperandsCount == 2) { operationsStack.PushBinaryOperator(operation); break; } // Ternary and more if (operation.OperandsCount > 2) { int partNumber = 0; for (int k = 0; k < operation.Signature.Length; k++) { if (operation.Signature[k] == item.Signature) { partNumber = k + 1; break; } } // If it is start part in signature if (partNumber == 1) { operationsStack.PushComplexOperatorFirstSignature(operation); break; } // operationsStack.PushComplexOperatorNonFirstSignature(operation, partNumber); break; } } // Function if (operation.Kind == OperationKind.Function) { operationsStack.PushFunction(operation); break; } } } } // operationsStack.DoFinalFlush(); // CompiledExpression res = operationsStack.GetResult(); if (!isCompiledExpressionStackBalanced(res)) { throw new CompilerSyntaxException("Operands disbalance detected."); } return(res); }
/// <summary> /// Returns a compiled expression for specified source string. /// </summary> public CompiledExpression Compile(PreparedExpression preparedExpression) { if (preparedExpression == null) throw new ArgumentNullException("preparedExpression"); // OperationsStack operationsStack = new OperationsStack(operationsRegistry); // for (int itemIndex = 0; itemIndex < preparedExpression.PreparedExpressionItems.Count; itemIndex++) { PreparedExpressionItem item = preparedExpression.PreparedExpressionItems[itemIndex]; // If constant or variable - add to result if (item.Kind == PreparedExpressionItemKind.Constant) operationsStack.PushConstant(item.Constant); if (item.Kind == PreparedExpressionItemKind.Variable) operationsStack.PushVariable(item.VariableName); // If delimiter if (item.Kind == PreparedExpressionItemKind.Delimiter) { operationsStack.PushDelimiter(item.DelimiterKind); } // Signature (operator signature / part of signature / function) if (item.Kind == PreparedExpressionItemKind.Signature) { List<Operation> operations = new List<Operation>(operationsRegistry.GetOperationsUsingSignature(item.Signature)); operations.Sort(new Comparison<Operation>(compareOperationsByOperandsCount)); // for (int i = 0; i < operations.Count; i++) { Operation operation = operations[i]; // Operator if (operation.Kind == OperationKind.Operator) { // Unary operator if (operation.OperandsCount == 1) { // If operator placed at the start of subexpression if ((itemIndex == 0) || ((itemIndex > 0) && (preparedExpression.PreparedExpressionItems[itemIndex - 1].Kind == PreparedExpressionItemKind.Delimiter) && (preparedExpression.PreparedExpressionItems[itemIndex - 1].DelimiterKind == DelimiterKind.OpeningBrace)|| (preparedExpression.PreparedExpressionItems[itemIndex-1].DelimiterKind == DelimiterKind.Comma))) { // operationsStack.PushUnaryOperator(operation); break; } } // Binary operator if (operation.OperandsCount == 2) { operationsStack.PushBinaryOperator(operation); break; } // Ternary and more if (operation.OperandsCount > 2) { int partNumber = 0; for (int k = 0; k < operation.Signature.Length; k++) { if (operation.Signature[k] == item.Signature) { partNumber = k + 1; break; } } // If it is start part in signature if (partNumber == 1) { operationsStack.PushComplexOperatorFirstSignature(operation); break; } // operationsStack.PushComplexOperatorNonFirstSignature(operation, partNumber); break; } } // Function if (operation.Kind == OperationKind.Function) { operationsStack.PushFunction(operation); break; } } } } // operationsStack.DoFinalFlush(); // CompiledExpression res = operationsStack.GetResult(); if (!isCompiledExpressionStackBalanced(res)) throw new CompilerSyntaxException("Operands disbalance detected."); return res; }