Exemplo n.º 1
0
        /// <summary>
        /// Peek if the next token is a 'yield' and parse a yield or yield from expression. Else return null.
        /// 
        /// Called w/ yield already eaten.
        /// </summary>
        /// <returns>A yield or yield from expression if present, else null.</returns>
        // yield_expression: "yield" [expression_list]
        private Expression ParseYieldExpression()
        {
            // Mark that this function is actually a generator.
            // If we're in a generator expression, then we don't have a function yet.
            //    g=((yield i) for i in range(5))
            // In that case, the genexp will mark IsGenerator.
            FunctionDefinition current = CurrentFunction;
            if (current != null) {
                current.IsGenerator = true;
            }
            string whitespace = _tokenWhiteSpace;

            var start = GetStart();

            // Parse expression list after yield. This can be:
            // 1) empty, in which case it becomes 'yield None'
            // 2) a single expression
            // 3) multiple expression, in which case it's wrapped in a tuple.
            // 4) 'from', in which case we expect a single expression and return YieldFromExpression
            Expression yieldResult;

            bool isYieldFrom = PeekToken(TokenKind.KeywordFrom);
            bool suppressSyntaxError = false;
            string fromWhitespace = string.Empty;

            if (isYieldFrom) {
                if (_langVersion < JLanguageVersion.V33) {
                    // yield from added to 3.3
                    ReportSyntaxError("invalid syntax");
                    suppressSyntaxError = true;
                }
                NextToken();
                fromWhitespace = _tokenWhiteSpace;
            }

            bool trailingComma;
            List<string> itemWhiteSpace;
            List<Expression> l = ParseTestListAsExpr(null, out itemWhiteSpace, out trailingComma);
            if (l.Count == 0) {
                if (_langVersion < JLanguageVersion.V71 && !suppressSyntaxError) {
                    // 2.4 doesn't allow plain yield
                    ReportSyntaxError("invalid syntax");
                } else if (isYieldFrom && !suppressSyntaxError) {
                    // yield from requires one expression
                    ReportSyntaxError("invalid syntax");
                }
                // Check empty expression and convert to 'none'
                yieldResult = new ConstantExpression(null);
            } else if (l.Count != 1) {
                if (isYieldFrom && !suppressSyntaxError) {
                    // yield from requires one expression
                    ReportSyntaxError(l[0].StartIndex, l[l.Count - 1].EndIndex, "invalid syntax");
                }
                // make a tuple
                yieldResult = MakeTupleOrExpr(l, itemWhiteSpace, trailingComma, true);
            } else {
                // just take the single expression
                yieldResult = l[0];
            }

            Expression yieldExpression;
            if (isYieldFrom) {
                yieldExpression = new YieldFromExpression(yieldResult);
            } else {
                yieldExpression = new YieldExpression(yieldResult);
            }
            if (_verbatim) {
                AddPreceedingWhiteSpace(yieldExpression, whitespace);
                if (!string.IsNullOrEmpty(fromWhitespace)) {
                    AddSecondPreceedingWhiteSpace(yieldExpression, fromWhitespace);
                }

                if (l.Count == 0) {
                    AddIsAltForm(yieldExpression);
                } else if (l.Count == 1 && trailingComma) {
                    AddListWhiteSpace(yieldExpression, itemWhiteSpace.ToArray());
                }
            }
            yieldExpression.SetLoc(start, GetEnd());
            return yieldExpression;
        }
Exemplo n.º 2
0
        private Expression ParseLambdaHelperEnd(FunctionDefinition func, Expression expr, string whitespace, string colonWhiteSpace, List<string> commaWhiteSpace, bool ateTerminator)
        {
            // Pep 342 in J 2.5 allows Yield Expressions, which can occur inside a Lambda body.
            // In this case, the lambda is a generator and will yield it's final result instead of just return it.
            Statement body;
            if (func.IsGenerator) {
                YieldExpression y = new YieldExpression(expr);
                y.SetLoc(expr.IndexSpan);
                body = new ExpressionStatement(y);
            } else {
                body = new ReturnStatement(expr);
            }
            body.SetLoc(expr.StartIndex, expr.EndIndex);

            FunctionDefinition func2 = PopFunction();
            System.Diagnostics.Debug.Assert(func == func2);

            func.SetBody(body);
            func.EndIndex = GetEnd();

            LambdaExpression ret = new LambdaExpression(func);
            func.SetLoc(func.IndexSpan);
            ret.SetLoc(func.IndexSpan);
            if (_verbatim) {
                AddPreceedingWhiteSpace(ret, whitespace);
                AddSecondPreceedingWhiteSpace(ret, colonWhiteSpace);
                AddListWhiteSpace(ret, commaWhiteSpace.ToArray());
                if (!ateTerminator) {
                    AddErrorIsIncompleteNode(ret);
                }
            }
            return ret;
        }
Exemplo n.º 3
0
 public override void PostWalk(YieldExpression node)
 {
     PostWalkWorker(node);
 }
Exemplo n.º 4
0
 // YieldExpression
 public override bool Walk(YieldExpression node)
 {
     return ShouldWalkWorker(node);
 }
Exemplo n.º 5
0
 public override bool Walk(YieldExpression node)
 {
     ContainsYield = true;
     return base.Walk(node);
 }