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; } }
public void IsOperator(TokenType input) { Assert.True(TokenIdentifier.IsOperator(input)); }
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; } }