Example #1
0
        // expr_stmt: expression_list
        // expression_list: expression ( "," expression )* [","] 
        // assignment_stmt: (target_list "=")+ (expression_list | yield_expression) 
        // augmented_assignment_stmt ::= target augop (expression_list | yield_expression) 
        // augop: '+=' | '-=' | '*=' | '/=' | '%=' | '**=' | '>>=' | '<<=' | '&=' | '^=' | '|=' | '//='
        private Statement ParseExprStmt() {
            Expression ret = ParseTestListAsExpr();

            if (PeekToken(TokenKind.Assign)) {
                if (_langVersion >= PythonLanguageVersion.V30) {
                    SequenceExpression seq = ret as SequenceExpression;
                    bool hasStar = false;
                    if (seq != null) {
                        for (int i = 0; i < seq.Items.Count; i++) {
                            if (seq.Items[i] is StarredExpression) {
                                if (hasStar) {
                                    ReportSyntaxError(seq.Items[i].StartIndex, seq.Items[i].EndIndex, "two starred expressions in assignment");
                                }
                                hasStar = true;
                            }
                        }
                    }
                }

                return FinishAssignments(ret);
            } else {
                PythonOperator op = GetAssignOperator(PeekToken());
                if (op != PythonOperator.None) {
                    NextToken();
                    string whiteSpace = _tokenWhiteSpace;
                    Expression rhs;

                    if (_langVersion >= PythonLanguageVersion.V25 && PeekToken(TokenKind.KeywordYield)) {
                        if (!AllowYieldSyntax && AllowAsyncAwaitSyntax) {
                            ReportSyntaxError("'yield' inside async function");
                        }
                        Eat(TokenKind.KeywordYield);
                        rhs = ParseYieldExpression();
                    } else {
                        rhs = ParseTestListAsExpr();
                    }

                    string assignError = ret.CheckAugmentedAssign();
                    if (assignError != null) {
                        ReportSyntaxError(ret.StartIndex, ret.EndIndex, assignError);
                    }

                    AugmentedAssignStatement aug = new AugmentedAssignStatement(op, ret, rhs);
                    if (_verbatim) {
                        AddPreceedingWhiteSpace(aug, whiteSpace);
                    }
                    aug.SetLoc(ret.StartIndex, GetEnd());
                    return aug;
                } else {
                    Statement stmt = new ExpressionStatement(ret);
                    stmt.SetLoc(ret.IndexSpan);
                    return stmt;
                }
            }
        }
Example #2
0
        private Statement ParseYieldStmt() {
            // For yield statements, continue to enforce that it's currently in a function. 
            // This gives us better syntax error reporting for yield-statements than for yield-expressions.
            if (!AllowYieldSyntax) {
                if (AllowAsyncAwaitSyntax) {
                    ReportSyntaxError("'yield' inside async function");
                } else {
                    ReportSyntaxError("misplaced yield");
                }
            }

            _isGenerator = true;
            if (_returnsWithValue != null && _langVersion < PythonLanguageVersion.V33) {
                foreach (var span in _returnsWithValue) {
                    ReportSyntaxError(span.Start, span.End, "'return' with argument inside generator");
                }
            }

            Eat(TokenKind.KeywordYield);

            // See Pep 342: a yield statement is now just an expression statement around a yield expression.
            Expression e = ParseYieldExpression();
            Debug.Assert(e != null); // caller already verified we have a yield.

            Statement s = new ExpressionStatement(e);
            s.SetLoc(e.IndexSpan);
            return s;
        }