예제 #1
0
        public Expr Parse(TokenStream stream)
        {
            // Parse the left side of the expression.
            Expr leftSide = new PrimaryExprParser().Parse(stream);

            // Ensure left side was successfully parsed, otherwise return null.
            if (leftSide == null)
            {
                return(null);
            }

            // Invoke the binary expression parser.
            Expr expr = new BinaryOpRightSideParser(leftSide, 0).Parse(stream);

            // Return the parsed expression.
            return(expr);
        }
예제 #2
0
        public Expr Parse(ParserContext context)
        {
            // Parse the left side of the expression.
            Expr leftSide = new PrimaryExprParser().Parse(context);

            // Ensure left side was successfully parsed, otherwise throw an error.
            if (leftSide == null)
            {
                throw new Exception("Unexpected expression left-side to be null");
            }

            // Invoke the binary expression parser, for potential following expression(s).
            Expr expr = new BinaryOpRightSideParser(leftSide, 0).Parse(context);

            // Return the parsed expression.
            return(expr);
        }
예제 #3
0
        public Expr Parse(ParserContext context)
        {
            // If this is a binary operation, find it's precedence.
            while (true)
            {
                // Capture the current token.
                Token token = context.Stream.Current;

                // Calculate precedence for the current token.
                int firstPrecedence = Precedence.Get(token);

                /*
                 * If this is a binary operation that binds at least as tightly
                 * as the current binary operation, consume it. Otherwise, the process
                 * is complete.
                 */
                if (firstPrecedence < this.minimalPrecedence)
                {
                    // TODO: This should throw error? Research.
                    return(this.leftSide);
                }

                // At this point, it's a binary operation.
                TokenType binaryOperator = token.Type;

                // TODO: Should check if it's a BINARY operator, not just an operator.
                // Ensure the captured operator is validated.
                if (!TokenIdentifier.IsOperator(binaryOperator))
                {
                    throw context.NoticeRepository.CreateException($"Expected token to be a binary operator but got token type '{binaryOperator}'");
                }

                // Skip operator.
                context.Stream.Skip();

                // Parse the right-side.
                Expr rightSide = new PrimaryExprParser().Parse(context);

                // Ensure that the right-side was successfully parsed.
                if (rightSide == null)
                {
                    throw new Exception("Unable to parse the right-side of the binary expression");
                }

                // Determine the token precedence of the current token.
                int secondPrecedence = Precedence.Get(token);

                /*
                 * If binary operator binds less tightly with the right-side than
                 * the operator after right-side, let the pending operator take the
                 * right-side as its left-side.
                 */
                if (firstPrecedence < secondPrecedence)
                {
                    // Invoke the right-side parser.
                    rightSide = new BinaryOpRightSideParser(rightSide, firstPrecedence + 1).Parse(context);

                    // Ensure the right-side was successfully parsed.
                    if (rightSide == null)
                    {
                        throw new Exception("Unable to parse the right-side of the binary expression");
                    }
                }

                // Create the binary expression entity.
                BinaryExpr binaryExpr = new BinaryExpr(binaryOperator, this.leftSide, rightSide, firstPrecedence);

                // TODO: Name is temporary?
                // Set the name of the binary expression's output.
                binaryExpr.SetName("tmp");

                // Merge left-side/right-side.
                this.leftSide = binaryExpr;
            }
        }
예제 #4
0
        public Expr Parse(TokenStream stream)
        {
            // If this is a binary operation, find it's precedence.
            while (true)
            {
                var firstPrecedence = Precedence.Get(stream.Get());

                /*
                 * If this is a binary operation that binds at least as tightly
                 * as the current binary operation, consume it. Otherwise, the process
                 * is complete.
                 */
                if (firstPrecedence < minimalPrecedence)
                {
                    return(leftSide);
                }

                // At this point, it's a binary operation.
                TokenType binaryOperator = stream.Get().Type;

                // TODO: Should check if it's a BINARY operator, not just an operator.
                // Ensure the captured operator is validated.
                if (!TokenIdentifier.IsOperator(binaryOperator))
                {
                    throw new Exception(
                              $"Expected token to be a binary operator but got token type '{binaryOperator}'");
                }

                // Skip operator.
                stream.Skip();

                // Parse the right-side.
                Expr rightSide = new PrimaryExprParser().Parse(stream);

                // Ensure that the right-side was successfully parsed.
                if (rightSide == null)
                {
                    throw new Exception("Unable to parse the right-side of the binary expression");
                }

                // Determine the token precedence of the current token.
                var secondPrecedence = Precedence.Get(stream.Get());

                /*
                 * If binary operator binds less tightly with the right-side than
                 * the operator after right-side, let the pending operator take the
                 * right-side as its left-side.
                 */
                if (firstPrecedence < secondPrecedence)
                {
                    // Invoke the right-side parser.
                    rightSide = new BinaryOpRightSideParser(rightSide, firstPrecedence + 1).Parse(stream);

                    // Ensure the right-side was successfully parsed.
                    if (rightSide == null)
                    {
                        throw new Exception("Unable to parse the right-side of the binary expression");
                    }
                }

                // Create the binary expression entity.
                var binaryExpr = new BinaryExpr(leftSide, rightSide, firstPrecedence);

                // Merge left-side/right-side.
                leftSide = binaryExpr;
            }
        }