protected virtual void VisitAssignToken(BinaryToken token) { VisitBinaryToken(token, Symbols.AssignVal); }
protected virtual void VisitAndToken(BinaryToken token) { VisitBinaryToken(token, Symbols.AndVal); }
protected virtual void VisitOrToken(BinaryToken token) { VisitBinaryToken(token, Symbols.OrVal); }
protected virtual void VisitNotGreaterToken(BinaryToken token) { VisitBinaryToken(token, Symbols.NotGreaterVal); }
protected virtual void VisitGreaterOrEqualToken(BinaryToken token) { VisitBinaryToken(token, Symbols.GreaterOrEqualVal); }
protected virtual void VisitNotLessToken(BinaryToken token) { VisitBinaryToken(token, Symbols.NotLessVal); }
protected virtual void VisitLessOrEqualToken(BinaryToken token) { VisitBinaryToken(token, Symbols.LessOrEqualVal); }
protected virtual void VisitBinaryToken(BinaryToken token, string operation) { VisitToken(token.First); State.Write(operation); VisitToken(token.Second); }
protected virtual void VisitIsEqualsToken(BinaryToken token) { VisitBinaryToken(token, Symbols.EqualsVal); }
private static FormulaNode Parse(List <Token> tokens) { FormulaNode result = null; List <Token> rightSide = new List <Token>(); BinaryToken lastOp = null; // the input is a single token - must be an atom or an unparsed string if (tokens.Count == 1) { var tok = tokens[0] as LiteralToken; if (tok.type == TokenType.ATOM) { return(new FormulaNode(tok.value)); } return(Parse(ToplevelTokenize(tok.value))); } int minPrecedence = MAX_PRECEDENCE; for (int i = 0; i < tokens.Count; i++) { if (tokens[i] is BinaryToken) { var op = tokens[i] as BinaryToken; minPrecedence = Math.Min(minPrecedence, op.precedence); } } if (minPrecedence == MAX_PRECEDENCE) { // the input didn't contain any toplevel binary operators var opToken = tokens[0] as UnaryToken; result = new FormulaNode(opToken.logicOperator); var operand = Parse(tokens.GetRange(1, tokens.Count - 1)); if (untilOperators.Contains(opToken.logicOperator)) { result.SetChildren(operand[0], operand[1]); } else if (quanitifers.Contains(opToken.logicOperator)) { result.SetName(operand[0].GetName()); result.SetChildren(operand[1], null); } else { result.SetChildren(operand, null); } return(result); } // if we got here - split by lowest-precedence binary operator foreach (Token t in tokens) { if (t is BinaryToken) { var op = t as BinaryToken; if (op.precedence == minPrecedence) { if (result == null) { result = Parse(rightSide); } else { var leftSide = result; result = new FormulaNode(lastOp.logicOperator); result.SetChildren(leftSide, Parse(rightSide)); } rightSide = new List <Token>(); lastOp = op; continue; } } rightSide.Add(t); } if (rightSide.Count != 0) { var leftSide = result; result = new FormulaNode(lastOp.logicOperator); result.SetChildren(leftSide, Parse(rightSide)); } return(result); }
protected TokenImpl ApplyPrecedence(ExpressionCompiler compiler, BinaryToken lhs, BinaryToken newToken) { // If the left-hand side is a binary token, and the new token has a higher precedence, // then take the right-hand side from the old left-hand side and use that as the left // hand side on the new token. The new token then becomes the right-hand side of the left // hand side. int lhsPrecedence = compiler.GetPrecedence(lhs.GetType()); int newPrecedence = compiler.GetPrecedence(newToken.GetType()); if (newPrecedence < lhsPrecedence) { newToken.Lhs = lhs.Rhs; lhs.Rhs = newToken; return(lhs); } else { return(newToken); } }
public override bool Parse(ExpressionCompiler compiler) { int symbolPos = compiler.Pos; if (!base.Parse(compiler)) { return(false); } // Must have a left-hand side... if (compiler.Parent.Children.Count == 0) { // Reset the compiler position compiler.Pos = symbolPos; // We don't throw an exception so the compiler will then check to see // if the symbol represents a group instead return(false); } TokenImpl lhs = compiler.Parent.PopChild(); FunctionToken function = null; if (lhs is HostSupport) { function = new FunctionToken(symbolPos, lhs); compiler.Parent.AddChild(function); } else if (lhs is BinaryToken) { // If the RHS of the binary token is token which supports hosting we can join to and replace it BinaryToken binaryLhs = (BinaryToken)lhs; TokenImpl lhsRhs = binaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it function = new FunctionToken(symbolPos, lhsRhs); binaryLhs.Rhs = function; compiler.Parent.AddChild(binaryLhs); } } else if (lhs is UnaryToken) { // If the RHS of the unary token is token which supports hosting we can join to and replace it UnaryToken unaryLhs = (UnaryToken)lhs; TokenImpl lhsRhs = unaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it function = new FunctionToken(symbolPos, lhsRhs); unaryLhs.Rhs = function; compiler.Parent.AddChild(unaryLhs); } } if (function == null) { // Restore the lhs and position compiler.Parent.AddChild(lhs); compiler.Pos = symbolPos; // Couldn't handle the lhs, just return false to continue to parse as a group return(false); } // The function becomes the new parent token compiler.ParentTokens.Push(function); // Keep parsing until we are closed while (!function.IsClosed) { if (!compiler.ParseNextToken()) { throw new ParserException(function, "Unclosed function"); } } return(true); }
public override bool Parse(ExpressionCompiler compiler) { int symbolPos = compiler.Pos; if (!base.Parse(compiler)) { return(false); } // Must have a left-hand side... if (compiler.Parent.Children.Count == 0) { // Reset the compiler position compiler.Pos = symbolPos; throw new ParserException("keyedAccess", symbolPos, "Missing left-hand operand"); } TokenImpl lhs = compiler.Parent.PopChild(); // See if we can handle the lhs KeyedAccessToken keyedAccess = null; if (lhs is HostSupport) { keyedAccess = new KeyedAccessToken(symbolPos, lhs); compiler.Parent.AddChild(keyedAccess); } else if (lhs is BinaryToken) { // If the RHS of the binary token is token which allows Hosting we can join to and replace it BinaryToken binaryLhs = (BinaryToken)lhs; TokenImpl lhsRhs = binaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it keyedAccess = new KeyedAccessToken(symbolPos, lhsRhs); binaryLhs.Rhs = keyedAccess; compiler.Parent.AddChild(binaryLhs); } } else if (lhs is UnaryToken) { // If the RHS of the unary token is which which allows Hosting we can join to and replace it UnaryToken unaryLhs = (UnaryToken)lhs; TokenImpl lhsRhs = unaryLhs.Rhs; if (lhsRhs is HostSupport) { // We can join it keyedAccess = new KeyedAccessToken(symbolPos, lhsRhs); unaryLhs.Rhs = keyedAccess; compiler.Parent.AddChild(unaryLhs); } } // Throw an exception if we couldn't cope with the lhs. if (keyedAccess == null) { // Restore the lhs and position compiler.Parent.AddChild(lhs); compiler.Pos = symbolPos; throw new ParserException("keyedAccess", symbolPos, $"Left-hand side of a keyed access token cannot be: {lhs.Name}"); } // The keyed access becomes the new parent token compiler.ParentTokens.Push(keyedAccess); // Keep parsing until we are closed while (!keyedAccess.IsClosed) { if (!compiler.ParseNextToken()) { throw new ParserException(keyedAccess, "Unclosed keyed access"); } } return(true); }
protected virtual void VisitLikeToken(BinaryToken token) { VisitToken(token.First); State.Write(Symbols.LIKE); VisitToken(token.Second); }