public bool Parse(ExpressionCompiler compiler)
    {
        int startPos = compiler.Pos;

        if (!testSymbol.Parse(compiler))
        {
            return(false);
        }

        // Must have a left-hand side...
        if (compiler.Parent.Children.Count == 0)
        {
            // Reset the compiler position
            compiler.Pos = startPos;

            throw new ParserException(Name, startPos, "Missing operand for the test");
        }
        TokenImpl test = compiler.Parent.PopChild();

        // Parse the result if true token
        if (!compiler.ParseNextToken())
        {
            // Reset the compiler position and restore the removed child
            compiler.Pos = startPos;
            compiler.Parent.AddChild(test);

            throw new ParserException(Name, startPos, "Missing operand for result if true");
        }
        TokenImpl resultIfTrue = compiler.Parent.PopChild();

        // Must have the 'else' token next
        if (!elseSymbol.Parse(compiler))
        {
            // Reset the compiler position and restore the (first) removed child
            compiler.Pos = startPos;
            compiler.Parent.AddChild(test);

            throw new ParserException(Name, startPos, "Missing ':' symbol");
        }

        // Parse the result if false token
        if (!compiler.ParseNextToken())
        {
            // Reset the compiler position and restore the (first) removed child
            compiler.Pos = startPos;
            compiler.Parent.AddChild(test);

            throw new ParserException(Name, startPos, "Missing operand for result if false");
        }
        TokenImpl resultIfFalse = compiler.Parent.PopChild();

        TokenImpl token = new ConditionalOperatorToken(startPos, test, resultIfTrue, resultIfFalse);

        compiler.Parent.AddChild(token);
        return(true);
    }
示例#2
0
    public bool Parse(ExpressionCompiler compiler)
    {
        int symbolPos = compiler.Pos;

        if (!symbolParser.Parse(compiler))
        {
            return(false);
        }

        // Parse the right hand side
        if (!compiler.ParseNextToken())
        {
            // Reset the compiler position
            compiler.Pos = symbolPos;

            throw new ParserException(Name, symbolPos, "Missing right-hand operand");
        }
        TokenImpl rhs = compiler.Parent.PopChild();

        TokenImpl token = CreateToken(compiler, symbolPos, rhs);

        if (token != null)
        {
            compiler.Parent.AddChild(token);
        }

        return(true);
    }
示例#3
0
    public override bool Parse(ExpressionCompiler compiler)
    {
        int symbolPos = compiler.Pos;

        if (!base.Parse(compiler))
        {
            return(false);
        }

        // The group becomes the new parent token
        GroupToken group = new GroupToken(symbolPos);

        compiler.Parent.AddChild(group);
        compiler.ParentTokens.Push(group);

        // Keep parsing until we are closed
        while (!group.IsClosed)
        {
            if (!compiler.ParseNextToken())
            {
                throw new ParserException(group, "Unclosed group");
            }
        }

        return(true);
    }
示例#4
0
    public bool Parse(ExpressionCompiler compiler)
    {
        int symbolPos = compiler.Pos;

        if (!symbolParser.Parse(compiler))
        {
            return(false);
        }

        // Must have a left-hand side...
        if (compiler.Parent.Children.Count == 0)
        {
            // Reset the compiler position
            compiler.Pos = symbolPos;

            // If we are lenient to the left-hand side missing, just return false
            if (lhsLenient)
            {
                return(false);
            }
            else
            {
                throw new ParserException(Name, symbolPos, "Missing left-hand operand");
            }
        }
        TokenImpl lhs = compiler.Parent.PopChild();

        // Parse the right hand side
        if (!compiler.ParseNextToken())
        {
            // Reset the compiler position and restore the removed child
            compiler.Pos = symbolPos;
            compiler.Parent.AddChild(lhs);

            throw new ParserException(Name, symbolPos, "Missing right-hand operand");
        }
        TokenImpl rhs = compiler.Parent.PopChild();

        TokenImpl token = CreateToken(compiler, symbolPos, lhs, rhs);

        if (token != null)
        {
            compiler.Parent.AddChild(token);
        }

        return(true);
    }
示例#5
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);
    }
示例#6
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);
    }