internal DataExpression(DataTable?table, string?expression, Type?type) { ExpressionParser parser = new ExpressionParser(table); parser.LoadExpression(expression); _originalExpression = expression; _expr = null; // Note: nobody seems to pass a null expression in the codebase if (expression != null) { _storageType = DataStorage.GetStorageType(type); if (_storageType == StorageType.BigInteger) { throw ExprException.UnsupportedDataType(type !); } _dataType = type; _expr = parser.Parse(); _parsed = true; if (_expr != null && table != null) { Bind(table); } else { _bound = false; } } }
internal VariableDeclarationStatementNode(IdentifierNode identifier, TypeSpecNode?type, ExpressionNode?value, bool isReadOnly, int lineNumber, int index) : base(lineNumber, index) { VariableIdentifierNode = identifier; VariableIdentifierNode.ParentNode = this; TypeSpecNode = type; if (TypeSpecNode != null) { TypeSpecNode.ParentNode = this; } AssignedExpressionNode = value; if (AssignedExpressionNode != null) { AssignedExpressionNode.ParentNode = this; } IsReadOnly = isReadOnly; }
public ExpressionNode?ParseNextExpression(ref int index) { Debug.Assert(Lexemes.Count > index & index >= 0); ExpressionNode?expression = ParseNextExpressionInternal(ref index); index++; return(expression); }
public IEnumerable <string> Transform(ExtendsNode item) { if (ShouldRender == false) { throw new NotImplementedException(); } _NextTemplate = item.Template; yield break; }
public Select(DataTable table, string?filterExpression, string?sort, DataViewRowState recordStates) { _table = table; _indexFields = table.ParseSortString(sort); if (filterExpression != null && filterExpression.Length > 0) { _rowFilter = new DataExpression(_table, filterExpression); _expression = _rowFilter.ExpressionNode; } _recordStates = recordStates; }
internal static bool TryParseFor(JinjaEnvironment environment, Lexer lexer, ILookaroundEnumerator <ParsingNode> enumerator, [NotNullWhen(true)] out ASTNode?parsedNode) { ContainerNode? elseBlock = null; ExpressionNode?filterNode = null; parsedNode = default; if (ForParser.StartBlock.TryParse(enumerator.Current, out var outsideStart, out var primaryInsideStart) == false) { return(false); } var primaryStartParsingNode = enumerator.Current; if (ForParser.StartBlock.TryGetAccumulations(ForParser.ForState.VariableNames, out var variableNames) == false || variableNames.Length == 0) { throw new NotImplementedException(); } if (ForParser.StartBlock.TryGetAccumulation(ForParser.ForState.Expression, 0, out var expression) == false) { throw new NotImplementedException(); } if (ForParser.StartBlock.TryGetAccumulation(ForParser.ForState.Filter, 0, out string?filter)) { filterNode = ExpressionNode.FromString(environment, filter); } ForParser.StartBlock.TryGetVariable <bool>("recursive", out var recursive); enumerator.MoveNext(); var primaryBlockChildren = ASTGenerator.ParseUntilFailure(environment, lexer, enumerator).ToArray(); ContainerNode primaryBlock; if (ForParser.ElseBlock.TryParse(enumerator.Current, out var primaryInsideEnd, out var elseInsideStart)) { var elseStartParsingNode = enumerator.Current; enumerator.MoveNext(); var elseBlockChildren = ASTGenerator.ParseUntilFailure(environment, lexer, enumerator).ToArray(); if (ForParser.EndBlock.TryParse(enumerator.Current, out var elseInsideEnd, out var outsideEnd) == false) { throw new NotImplementedException(); } primaryBlock = new ContainerNode(primaryStartParsingNode, primaryBlockChildren, null, new WhiteSpaceControlSet(primaryInsideStart, primaryInsideEnd)); elseBlock = new ContainerNode(elseStartParsingNode, elseBlockChildren, null, new WhiteSpaceControlSet(elseInsideStart, elseInsideEnd)); parsedNode = new ForNode(primaryBlock, elseBlock, variableNames, ExpressionNode.FromString(environment, expression), filterNode, recursive, enumerator.Current, new WhiteSpaceControlSet(outsideStart, outsideEnd)); return(true); }
private StatementNode?ParseExpressionStatement(ref int index) { ExpressionNode?expression = expressionParser.ParseNextExpression(ref index); if (expression == null) { return(null); } return(expression switch { FunctionCallExpressionNode functionCall => ParseFunctionCallStatement(functionCall, ref index), IdentifierExpressionNode identifierExpression => ParseVariableAssignmentStatement(ref index, identifierExpression.IdentifierNode, expression), _ => Error(), });
internal ForNode(ContainerNode primaryBlock, ContainerNode?elseBlock, string[] variableNames, object?expression, ExpressionNode?filter, bool recursive, ParsingNode?endParsingNode, WhiteSpaceControlSet?whiteSpace = null) : base( startParsingNode: null, children: primaryBlock.YieldOne().Concat(elseBlock?.YieldOne() ?? Enumerable.Empty <ContainerNode>()), endParsingNode: endParsingNode ) { PrimaryBlock = primaryBlock; ElseBlock = elseBlock; VariableNames = variableNames; Filter = filter; WhiteSpaceControl = whiteSpace ?? new WhiteSpaceControlSet(); Recursive = recursive; AlreadyEvaluatedObject = expression; }
private ExpressionNode?ParseNextExpressionInternal(ref int index, bool includeOperations = true) { ExpressionNode?expression = ParseSubExpression(ref index); if (expression == null) { return(null); } ParseAfterSubExpression(ref expression, ref index, includeOperations); if (expression is BinaryOperationChain chain) { expression = chain.Resolve(); } return(expression); }
private void ParseAfterSubExpression(ref ExpressionNode?expression, ref int index, bool includeOperations = true) { while (true) { switch (Lexemes.TryGet(index + 1)) { case IOperatorLexeme operatorLexeme when includeOperations: index++; ParseOperationChain(operatorLexeme, ref expression, ref index); return; case SyntaxCharacterLexeme { SyntaxCharacter: SyntaxCharacter.ParenthesisOpening } : index++; ParseFunctionCall(ref expression, ref index); continue;
internal void Bind(DataTable?table) { _table = table; if (table == null) { return; } if (_expr != null) { Debug.Assert(_parsed, "Invalid calling order: Bind() before Parse()"); List <DataColumn> list = new List <DataColumn>(); _expr.Bind(table, list); _expr = _expr.Optimize(); _table = table; _bound = true; _dependency = list.ToArray(); } }
private ForStatementNode?ParseForStatement(ref int index) { int lineNumber = lexemes[index].LineNumber; int nodeIndex = lexemes[index].Index; index++; if (!ParseForVariableSpecification(ref index, out IdentifierNode? identifier, out ExpressionNode? initialValue, out bool declaresNew)) { return(null); } ExpressionNode?condition = null; if (lexemes.TryGet(index) is KeywordLexeme { Keyword: ReservedKeyword.While })
public IEnumerable <string> Transform(TemplateNode item) { var toRender = item; while (true) { foreach (var output in TransformAll(toRender.Children)) { yield return(output); } if (_NextTemplate == null) { break; } var nextTemplateObj = Environment.Evaluation.EvaluateDynamic(_NextTemplate.ExpressionParserNode, ExpressionParserTransformer); _NextTemplate = null; switch (nextTemplateObj) { case DynamicTemplate d: toRender = d.TemplateNode; break; case string templateName: var temp = Environment.GetDynamicTemplate(templateName); if (!(temp is DynamicTemplate dt)) { throw new NotImplementedException(); } toRender = dt.TemplateNode; break; default: throw new NotImplementedException(); } } }
internal ForStatementNode(IdentifierNode identifier, bool declaresNew, ExpressionNode?initialValue, ExpressionNode?condition, ExpressionNode?withValue, StatementCollectionNode statements, int lineNumber, int index) : base(lineNumber, index) { Debug.Assert((condition != null) | (withValue != null)); VariableIdentifierNode = identifier; identifier.ParentNode = this; DeclaresNew = declaresNew; InitialValueNode = initialValue; if (initialValue != null) { initialValue.ParentNode = this; } ConditionNode = condition; if (condition != null) { condition.ParentNode = this; } WithExpressionNode = withValue; if (withValue != null) { withValue.ParentNode = this; } StatementNodes = statements; StatementNodes.ParentNode = this; }
internal void LoadExpression(string?data) { int length; if (data == null) { length = 0; _text = new char[length + 1]; } else { length = data.Length; _text = new char[length + 1]; data.CopyTo(0, _text, 0, length); } _text[length] = '\0'; if (_expression != null) { // free all nodes _expression = null; } }
public (ExpressionNode?Node, SourceMode Mode) Parse(ref CharacterReader r) { ExpressionNode?rootNode = null; ExpressionNode?node = null; var(astNodes, mode) = BindingExpressionGrammar.Parse(ref r); foreach (var astNode in astNodes) { ExpressionNode?nextNode = null; switch (astNode) { case BindingExpressionGrammar.EmptyExpressionNode _: nextNode = new EmptyExpressionNode(); break; case BindingExpressionGrammar.NotNode _: nextNode = new LogicalNotNode(); break; case BindingExpressionGrammar.StreamNode _: nextNode = new StreamNode(); break; case BindingExpressionGrammar.PropertyNameNode propName: nextNode = new PropertyAccessorNode(propName.PropertyName, _enableValidation); break; case BindingExpressionGrammar.IndexerNode indexer: nextNode = new StringIndexerNode(indexer.Arguments); break; case BindingExpressionGrammar.AttachedPropertyNameNode attachedProp: nextNode = ParseAttachedProperty(attachedProp); break; case BindingExpressionGrammar.SelfNode _: nextNode = new SelfNode(); break; case BindingExpressionGrammar.AncestorNode ancestor: nextNode = ParseFindAncestor(ancestor); break; case BindingExpressionGrammar.NameNode elementName: nextNode = new ElementNameNode(_nameScope ?? throw new NotSupportedException("Invalid element name binding with null name scope!"), elementName.Name); break; case BindingExpressionGrammar.TypeCastNode typeCast: nextNode = ParseTypeCastNode(typeCast); break; } if (node is null) { rootNode = node = nextNode; } else { node.Next = nextNode; node = nextNode; } } return(rootNode, mode); }
// Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions private void AnalyzeExpression(BinaryNode expr) { Debug.Assert(_candidateColumns != null); if (_linearExpression == _expression) { return; } if (expr._op == Operators.Or) { _linearExpression = _expression; return; } else if (expr._op == Operators.And) { bool isLeft = false, isRight = false; if (expr._left is BinaryNode) { AnalyzeExpression((BinaryNode)expr._left); if (_linearExpression == _expression) { return; } isLeft = true; } else { UnaryNode?unaryNode = expr._left as UnaryNode; if (unaryNode != null) { while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop) { unaryNode = (UnaryNode)unaryNode._right; } if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode) { AnalyzeExpression((BinaryNode)(unaryNode._right)); if (_linearExpression == _expression) { return; } isLeft = true; } } } if (expr._right is BinaryNode) { AnalyzeExpression((BinaryNode)expr._right); if (_linearExpression == _expression) { return; } isRight = true; } else { UnaryNode?unaryNode = expr._right as UnaryNode; if (unaryNode != null) { while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop) { unaryNode = (UnaryNode)unaryNode._right; } if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode) { AnalyzeExpression((BinaryNode)(unaryNode._right)); if (_linearExpression == _expression) { return; } isRight = true; } } } if (isLeft && isRight) { return; } ExpressionNode e = isLeft ? expr._right : expr._left; _linearExpression = (_linearExpression == null ? e : new BinaryNode(_table, Operators.And, e, _linearExpression)); return; } else if (IsSupportedOperator(expr._op)) { if (expr._left is NameNode && expr._right is ConstNode) { ColumnInfo canColumn = _candidateColumns[((NameNode)(expr._left))._column !.Ordinal];
public ReturnNode(ExpressionNode inner) { Inner = inner; }
/// <summary> /// Builds expression tree for higher-precedence operator to be used as left /// operand of current operator. May cause errors - always do ErrorCheck() upin return. /// </summary> private void BuildExpression(int pri) { ExpressionNode?expr = null; Debug.Assert(pri > Operators.priStart && pri <= Operators.priMax, "Invalid priority value"); /* For all operators of higher or same precedence (we are always * left-associative) */ while (true) { Debug.Assert(_topOperator > 0, "Empty operator stack!!"); OperatorInfo opInfo = _ops[_topOperator - 1]; if (opInfo._priority < pri) { goto end_loop; } Debug.Assert(opInfo._priority >= pri, "Invalid prioriry value"); _topOperator--; ExpressionNode?nodeLeft; ExpressionNode nodeRight; switch (opInfo._type) { case Nodes.Binop: { // get right, left operands. Bind them. nodeRight = NodePop(); nodeLeft = NodePop(); /* This is the place to do type and other checks */ switch (opInfo._op) { case Operators.Between: case Operators.BetweenAnd: case Operators.BitwiseAnd: case Operators.BitwiseOr: case Operators.BitwiseXor: case Operators.BitwiseNot: throw ExprException.UnsupportedOperator(opInfo._op); case Operators.Is: case Operators.Or: case Operators.And: case Operators.EqualTo: case Operators.NotEqual: case Operators.Like: case Operators.LessThen: case Operators.LessOrEqual: case Operators.GreaterThen: case Operators.GreaterOrEqual: case Operators.In: break; default: Debug.Assert(opInfo._op == Operators.Plus || opInfo._op == Operators.Minus || opInfo._op == Operators.Multiply || opInfo._op == Operators.Divide || opInfo._op == Operators.Modulo, "Invalud Binary operation"); break; } Debug.Assert(nodeLeft != null, "Invalid left operand"); Debug.Assert(nodeRight != null, "Invalid right operand"); if (opInfo._op == Operators.Like) { expr = new LikeNode(_table, opInfo._op, nodeLeft, nodeRight); } else { expr = new BinaryNode(_table, opInfo._op, nodeLeft, nodeRight); } break; } case Nodes.Unop: /* Unary operator: Pop and bind right op. */ nodeLeft = null; nodeRight = NodePop(); /* Check for special cases */ switch (opInfo._op) { case Operators.Not: break; case Operators.BitwiseNot: throw ExprException.UnsupportedOperator(opInfo._op); case Operators.Negative: break; } Debug.Assert(nodeLeft == null, "Invalid left operand"); Debug.Assert(nodeRight != null, "Invalid right operand"); expr = new UnaryNode(_table, opInfo._op, nodeRight); break; case Nodes.Zop: /* Intrinsic constant: just create node. */ expr = new ZeroOpNode(opInfo._op); break; default: Debug.Fail("Unhandled operator type"); goto end_loop; } Debug.Assert(expr != null, "Failed to create expression"); NodePush(expr); // countinue while loop; } end_loop: ; }
// CONSIDER: configure the scanner : local info internal ExpressionNode Parse() { // free all nodes _expression = null; StartScan(); int cParens = 0; OperatorInfo opInfo; while (_token != Tokens.EOS) { loop: Scan(); switch (_token) { case Tokens.EOS: // End of string: must be operand; force out expression; // check for bomb; check nothing left on stack. if (_prevOperand == Empty) { if (_topNode == 0) { // we have an empty expression break; } // set error missing operator // read the last operator info opInfo = _ops[_topOperator - 1]; throw ExprException.MissingOperand(opInfo); } // collect all nodes BuildExpression(Operators.priLow); if (_topOperator != 1) { throw ExprException.MissingRightParen(); } break; case Tokens.Name: case Tokens.Parent: case Tokens.Numeric: case Tokens.Decimal: case Tokens.Float: case Tokens.StringConst: case Tokens.Date: ExpressionNode?node = null; string? str = null; /* Constants and identifiers: create leaf node */ if (_prevOperand != Empty) { // set error missing operator throw ExprException.MissingOperator(new string(_text, _start, _pos - _start)); } if (_topOperator > 0) { // special check for IN without parentheses opInfo = _ops[_topOperator - 1]; if (opInfo._type == Nodes.Binop && opInfo._op == Operators.In && _token != Tokens.Parent) { throw ExprException.InWithoutParentheses(); } } _prevOperand = Scalar; switch (_token) { case Tokens.Parent: string?relname; string colname; // parsing Parent[(relation_name)].column_name) try { // expecting an '(' or '.' Scan(); if (_token == Tokens.LeftParen) { //read the relation name ScanToken(Tokens.Name); relname = NameNode.ParseName(_text, _start, _pos); ScanToken(Tokens.RightParen); ScanToken(Tokens.Dot); } else { relname = null; CheckToken(Tokens.Dot); } } catch (Exception e) when(Common.ADP.IsCatchableExceptionType(e)) { throw ExprException.LookupArgument(); } ScanToken(Tokens.Name); colname = NameNode.ParseName(_text, _start, _pos); opInfo = _ops[_topOperator - 1]; node = new LookupNode(_table, colname, relname); break; case Tokens.Name: /* Qualify name now for nice error checking */ opInfo = _ops[_topOperator - 1]; /* Create tree element - */ // CONSIDER: Check for reserved proc names here node = new NameNode(_table, _text, _start, _pos); break; case Tokens.Numeric: str = new string(_text, _start, _pos - _start); node = new ConstNode(_table, ValueType.Numeric, str); break; case Tokens.Decimal: str = new string(_text, _start, _pos - _start); node = new ConstNode(_table, ValueType.Decimal, str); break; case Tokens.Float: str = new string(_text, _start, _pos - _start); node = new ConstNode(_table, ValueType.Float, str); break; case Tokens.StringConst: Debug.Assert(_text[_start] == '\'' && _text[_pos - 1] == '\'', "The expression contains an invalid string constant"); Debug.Assert(_pos - _start > 1, "The expression contains an invalid string constant"); // Store string without quotes.. str = new string(_text, _start + 1, _pos - _start - 2); node = new ConstNode(_table, ValueType.Str, str); break; case Tokens.Date: Debug.Assert(_text[_start] == '#' && _text[_pos - 1] == '#', "The expression contains invalid date constant."); Debug.Assert(_pos - _start > 2, "The expression contains invalid date constant '{0}'."); // Store date without delimiters(#s).. str = new string(_text, _start + 1, _pos - _start - 2); node = new ConstNode(_table, ValueType.Date, str); break; default: Debug.Fail("unhandled token"); break; } NodePush(node); goto loop; case Tokens.LeftParen: cParens++; if (_prevOperand == Empty) { // Check for ( following IN/IFF. if not, we have a normal (. // Peek: take a look at the operators stack Debug.Assert(_topOperator > 0, "Empty operator stack!!"); opInfo = _ops[_topOperator - 1]; if (opInfo._type == Nodes.Binop && opInfo._op == Operators.In) { /* IN - handle as procedure call */ node = new FunctionNode(_table, "In"); NodePush(node); /* Push operator decriptor */ _ops[_topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.priParen); } else { /* Normal ( */ /* Push operator decriptor */ _ops[_topOperator++] = new OperatorInfo(Nodes.Paren, Operators.Noop, Operators.priParen); } } else { // This is a procedure call or () qualification // Force out any dot qualifiers; check for bomb BuildExpression(Operators.priProc); _prevOperand = Empty; ExpressionNode?nodebefore = NodePeek(); if (nodebefore == null || nodebefore.GetType() != typeof(NameNode)) { // this is more like an assert, so we not care about "nice" exception text.. throw ExprException.SyntaxError(); } /* Get the proc name */ NameNode name = (NameNode)NodePop(); // Make sure that we can bind the name as a Function // then get the argument count and types, and parse arguments.. node = new FunctionNode(_table, name._name); // check to see if this is an aggregate function Aggregate agg = (Aggregate)(int)((FunctionNode)node).Aggregate; if (agg != Aggregate.None) { node = ParseAggregateArgument((FunctionId)(int)agg); NodePush(node); _prevOperand = Expr; goto loop; } NodePush(node); _ops[_topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.priParen); } goto loop; case Tokens.RightParen: { /* Right parentheses: Build expression if we have an operand. */ if (_prevOperand != Empty) { BuildExpression(Operators.priLow); } /* We must have Tokens.LeftParen on stack. If no operand, must be procedure call. */ if (_topOperator <= 1) { // set error, syntax: too many right parens.. throw ExprException.TooManyRightParentheses(); } Debug.Assert(_topOperator > 1, "melformed operator stack."); _topOperator--; opInfo = _ops[_topOperator]; if (_prevOperand == Empty && opInfo._type != Nodes.Call) { // set error, syntax: missing operand. throw ExprException.MissingOperand(opInfo); } Debug.Assert(opInfo._priority == Operators.priParen, "melformed operator stack."); if (opInfo._type == Nodes.Call) { /* add argument to the function call. */ if (_prevOperand != Empty) { // read last function argument ExpressionNode argument = NodePop(); /* Get the procedure name and append argument */ Debug.Assert(_topNode > 0 && NodePeek() !.GetType() == typeof(FunctionNode), "The function node should be created on '('"); FunctionNode func = (FunctionNode)NodePop(); func.AddArgument(argument); func.Check(); NodePush(func); } } else { /* Normal parentheses: create tree node */ // Construct & Put the Nodes.Paren node on node stack node = NodePop(); node = new UnaryNode(_table, Operators.Noop, node); NodePush(node); } _prevOperand = Expr; cParens--; goto loop; } case Tokens.ListSeparator: { /* Comma encountered: Must be operand; force out subexpression */ if (_prevOperand == Empty) { throw ExprException.MissingOperandBefore(","); } /* We are be in a procedure call */ /* build next argument */ BuildExpression(Operators.priLow); opInfo = _ops[_topOperator - 1]; if (opInfo._type != Nodes.Call) { throw ExprException.SyntaxError(); } ExpressionNode argument2 = NodePop(); /* Get the procedure name */ FunctionNode func = (FunctionNode)NodePop(); func.AddArgument(argument2); NodePush(func); _prevOperand = Empty; goto loop; } case Tokens.BinaryOp: if (_prevOperand == Empty) { /* Check for unary plus/minus */ if (_op == Operators.Plus) { _op = Operators.UnaryPlus; // fall through to UnaryOperator; } else if (_op == Operators.Minus) { /* Unary minus */ _op = Operators.Negative; // fall through to UnaryOperator; } else { // Error missing operand: throw ExprException.MissingOperandBefore(Operators.ToString(_op)); } } else { _prevOperand = Empty; /* CNSIDER: If we are going to support BETWEEN Translate AND to special BetweenAnd if it is. */ /* Force out to appropriate precedence; push operator. */ BuildExpression(Operators.Priority(_op)); // PushOperator descriptor _ops[_topOperator++] = new OperatorInfo(Nodes.Binop, _op, Operators.Priority(_op)); goto loop; } goto case Tokens.UnaryOp; // fall through to UnaryOperator; case Tokens.UnaryOp: /* Must be no operand. Push it. */ _ops[_topOperator++] = new OperatorInfo(Nodes.Unop, _op, Operators.Priority(_op)); goto loop; case Tokens.ZeroOp: // check the we have operator on the stack if (_prevOperand != Empty) { // set error missing operator throw ExprException.MissingOperator(new string(_text, _start, _pos - _start)); } // PushOperator descriptor _ops[_topOperator++] = new OperatorInfo(Nodes.Zop, _op, Operators.priMax); _prevOperand = Expr; goto loop; case Tokens.Dot: //if there is a name on the stack append it. ExpressionNode?before = NodePeek(); if (before != null && before.GetType() == typeof(NameNode)) { Scan(); if (_token == Tokens.Name) { NameNode nameBefore = (NameNode)NodePop(); string newName = nameBefore._name + "." + NameNode.ParseName(_text, _start, _pos); NodePush(new NameNode(_table, newName)); goto loop; } } // fall through to default goto default; default: throw ExprException.UnknownToken(new string(_text, _start, _pos - _start), _start + 1); } } goto end_loop; end_loop: Debug.Assert(_topNode == 1 || _topNode == 0, "Invalid Node Stack"); _expression = _nodeStack[0]; return(_expression); }