예제 #1
0
 protected virtual void VisitAssignToken(BinaryToken token)
 {
     VisitBinaryToken(token, Symbols.AssignVal);
 }
예제 #2
0
 protected virtual void VisitAndToken(BinaryToken token)
 {
     VisitBinaryToken(token, Symbols.AndVal);
 }
예제 #3
0
 protected virtual void VisitOrToken(BinaryToken token)
 {
     VisitBinaryToken(token, Symbols.OrVal);
 }
예제 #4
0
 protected virtual void VisitNotGreaterToken(BinaryToken token)
 {
     VisitBinaryToken(token, Symbols.NotGreaterVal);
 }
예제 #5
0
 protected virtual void VisitGreaterOrEqualToken(BinaryToken token)
 {
     VisitBinaryToken(token, Symbols.GreaterOrEqualVal);
 }
예제 #6
0
 protected virtual void VisitNotLessToken(BinaryToken token)
 {
     VisitBinaryToken(token, Symbols.NotLessVal);
 }
예제 #7
0
 protected virtual void VisitLessOrEqualToken(BinaryToken token)
 {
     VisitBinaryToken(token, Symbols.LessOrEqualVal);
 }
예제 #8
0
 protected virtual void VisitBinaryToken(BinaryToken token, string operation)
 {
     VisitToken(token.First);
     State.Write(operation);
     VisitToken(token.Second);
 }
예제 #9
0
 protected virtual void VisitIsEqualsToken(BinaryToken token)
 {
     VisitBinaryToken(token, Symbols.EqualsVal);
 }
예제 #10
0
        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);
        }
예제 #11
0
    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);
        }
    }
예제 #12
0
    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);
    }
예제 #13
0
    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);
    }
예제 #14
0
 protected virtual void VisitLikeToken(BinaryToken token)
 {
     VisitToken(token.First);
     State.Write(Symbols.LIKE);
     VisitToken(token.Second);
 }