//simple_stmt: small_stmt (';' small_stmt)* [';'] Newline private Statement ParseSimpleStmt() { Statement s = ParseSmallStmt(); if (MaybeEat(TokenKind.Semicolon)) { var start = s.StartIndex; List<Statement> l = new List<Statement>(); l.Add(s); while (true) { if (MaybeEatNewLine() || MaybeEat(TokenKind.EndOfFile)) { break; } l.Add(ParseSmallStmt()); if (MaybeEat(TokenKind.EndOfFile)) { // implies a new line break; } else if (!MaybeEat(TokenKind.Semicolon)) { EatNewLine(); break; } } Statement[] stmts = l.ToArray(); SuiteStatement ret = new SuiteStatement(stmts); ret.SetLoc(_globalParent, start, stmts[stmts.Length - 1].EndIndex); return ret; } else if (!MaybeEat(TokenKind.EndOfFile) && !EatNewLine()) { // error handling, make sure we're making forward progress NextToken(); } return s; }
//suite: simple_stmt NEWLINE | Newline INDENT stmt+ DEDENT private Statement ParseSuite() { if (!EatNoEof(TokenKind.Colon)) { // improve error handling... return ErrorStmt(); } TokenWithSpan cur = _lookahead; List<Statement> l = new List<Statement>(); // we only read a real NewLine here because we need to adjust error reporting // for the interpreter. if (MaybeEat(TokenKind.NewLine)) { CheckSuiteEofError(cur); // for error reporting we track the NL tokens and report the error on // the last one. This matches CPython. cur = _lookahead; while (PeekToken(TokenKind.NLToken)) { cur = _lookahead; NextToken(); } if (!MaybeEat(TokenKind.Indent)) { // no indent? report the indentation error. if (cur.Token.Kind == TokenKind.Dedent) { ReportSyntaxError(_lookahead.Span.Start, _lookahead.Span.End, "expected an indented block", ErrorCodes.SyntaxError | ErrorCodes.IncompleteStatement); } else { ReportSyntaxError(cur, ErrorCodes.IndentationError); } return ErrorStmt(); } while (true) { Statement s = ParseStmt(); l.Add(s); if (MaybeEat(TokenKind.Dedent)) break; if (PeekToken().Kind == TokenKind.EndOfFile) { ReportSyntaxError("unexpected end of file"); break; // error handling } } Statement[] stmts = l.ToArray(); SuiteStatement ret = new SuiteStatement(stmts); ret.SetLoc(_globalParent, stmts[0].StartIndex, stmts[stmts.Length - 1].EndIndex); return ret; } else { // simple_stmt NEWLINE // ParseSimpleStmt takes care of the NEWLINE Statement s = ParseSimpleStmt(); return s; } }
private PythonAst ParseFileWorker(bool makeModule, bool returnValue) { _globalParent = new PythonAst(makeModule, _languageFeatures, false, _context); StartParsing(); List<Statement> l = new List<Statement>(); // // A future statement must appear near the top of the module. // The only lines that can appear before a future statement are: // - the module docstring (if any), // - comments, // - blank lines, and // - other future statements. // MaybeEatNewLine(); if (PeekToken(TokenKind.Constant)) { Statement s = ParseStmt(); l.Add(s); _fromFutureAllowed = false; ExpressionStatement es = s as ExpressionStatement; if (es != null) { ConstantExpression ce = es.Expression as ConstantExpression; if (ce != null && ce.Value is string) { // doc string _fromFutureAllowed = true; } } } MaybeEatNewLine(); // from __future__ if (_fromFutureAllowed) { while (PeekToken(Tokens.KeywordFromToken)) { Statement s = ParseStmt(); l.Add(s); FromImportStatement fis = s as FromImportStatement; if (fis != null && !fis.IsFromFuture) { // end of from __future__ break; } } } // the end of from __future__ sequence _fromFutureAllowed = false; while (true) { if (MaybeEat(TokenKind.EndOfFile)) break; if (MaybeEatNewLine()) continue; Statement s = ParseStmt(); l.Add(s); } Statement[] stmts = l.ToArray(); if (returnValue && stmts.Length > 0) { ExpressionStatement exprStmt = stmts[stmts.Length - 1] as ExpressionStatement; if (exprStmt != null) { var retStmt = new ReturnStatement(exprStmt.Expression); stmts[stmts.Length - 1] = retStmt; retStmt.SetLoc(_globalParent, exprStmt.Expression.IndexSpan); } } SuiteStatement ret = new SuiteStatement(stmts); ret.SetLoc(_globalParent, 0, GetEnd()); return FinishParsing(ret); }
//simple_stmt: small_stmt (';' small_stmt)* [';'] Newline private Statement ParseSimpleStmt() { Statement s = ParseSmallStmt(); if (MaybeEat(TokenKind.Semicolon)) { SourceLocation start = s.Start; List<Statement> l = new List<Statement>(); l.Add(s); while (true) { if (MaybeEat(TokenKind.NewLine)) break; l.Add(ParseSmallStmt()); if (!MaybeEat(TokenKind.Semicolon)) { Eat(TokenKind.NewLine); break; } if (MaybeEat(TokenKind.EndOfFile)) break; // error recovery } Statement[] stmts = l.ToArray(); SuiteStatement ret = new SuiteStatement(stmts); ret.SetLoc(start, GetEnd()); return ret; } else { if(!Eat(TokenKind.NewLine)) { // error handling, make sure we're making forward progress NextToken(); } return s; } }
//suite: simple_stmt NEWLINE | Newline INDENT stmt+ DEDENT private Statement ParseSuite() { if (!EatNoEof(TokenKind.Colon)) { // improve error handling... return new ExpressionStatement(new ErrorExpression()); } List<Statement> l = new List<Statement>(); if (MaybeEat(TokenKind.NewLine)) { if (!MaybeEat(TokenKind.Indent)) { ReportSyntaxError(_lookahead, ErrorCodes.IndentationError); return new ExpressionStatement(new ErrorExpression()); } while (true) { Statement s = ParseStmt(); l.Add(s); if (MaybeEat(TokenKind.Dedent)) break; if (PeekToken().Kind == TokenKind.EndOfFile) { ReportSyntaxError("unexpected end of file"); break; // error handling } } Statement[] stmts = l.ToArray(); SuiteStatement ret = new SuiteStatement(stmts); ret.SetLoc(stmts[0].Start, stmts[stmts.Length - 1].End); return ret; } else { // simple_stmt NEWLINE // ParseSimpleStmt takes care of the NEWLINE Statement s = ParseSimpleStmt(); return s; } }
//suite: simple_stmt NEWLINE | Newline INDENT stmt+ DEDENT private Statement ParseSuite() { EatNoEof(TokenKind.Colon); Location start = GetStart(); List<Statement> l = new List<Statement>(); if (MaybeEat(TokenKind.NewLine)) { if (!MaybeEat(TokenKind.Indent)) { ReportSyntaxError(NextToken(), ErrorCodes.IndentationError); } while (true) { Statement s = ParseStmt(); l.Add(s); if (MaybeEat(TokenKind.Dedent)) break; if (MaybeEat(TokenKind.EndOfFile)) break; // error recovery } Statement[] stmts = l.ToArray(); SuiteStatement ret = new SuiteStatement(stmts); ret.SetLoc(GetExternal(), start, GetEnd()); return ret; } else { // simple_stmt NEWLINE // ParseSimpleStmt takes care of the NEWLINE Statement s = ParseSimpleStmt(); return s; } }
//simple_stmt: small_stmt (';' small_stmt)* [';'] Newline private Statement ParseSimpleStmt() { Statement s = ParseSmallStmt(); if (MaybeEat(TokenKind.Semicolon)) { Location start = s.Start; List<Statement> l = new List<Statement>(); l.Add(s); while (true) { if (MaybeEat(TokenKind.NewLine)) break; l.Add(ParseSmallStmt()); if (!MaybeEat(TokenKind.Semicolon)) { Eat(TokenKind.NewLine); break; } if (MaybeEat(TokenKind.EndOfFile)) break; // error recovery } Statement[] stmts = l.ToArray(); SuiteStatement ret = new SuiteStatement(stmts); ret.SetLoc(GetExternal(), start, GetEnd()); return ret; } else { Eat(TokenKind.NewLine); return s; } }
//single_input: Newline | simple_stmt | compound_stmt Newline //eval_input: testlist Newline* ENDMARKER //file_input: (Newline | stmt)* ENDMARKER public Statement ParseFileInput() { List<Statement> l = new List<Statement>(); // // A future statement must appear near the top of the module. // The only lines that can appear before a future statement are: // - the module docstring (if any), // - comments, // - blank lines, and // - other future statements. // while (MaybeEat(TokenKind.NewLine)) ; if (PeekToken(TokenKind.Constant)) { Statement s = ParseStmt(); l.Add(s); fromFutureAllowed = false; if (s is ExpressionStatement) { ConstantExpression ce = ((ExpressionStatement)s).Expression as ConstantExpression; if (ce != null && ce.Value is string) { // doc string fromFutureAllowed = true; } } } while (MaybeEat(TokenKind.NewLine)) ; // from __future__ if (fromFutureAllowed) { while (PeekToken(Tokens.KeywordFromToken)) { Statement s = ParseStmt(); l.Add(s); if (s is FromImportStatement) { FromImportStatement fis = (FromImportStatement)s; if (!fis.IsFromFuture) { // end of from __future__ break; } } } } // the end of from __future__ sequence fromFutureAllowed = false; while (true) { if (MaybeEat(TokenKind.EndOfFile)) break; if (MaybeEat(TokenKind.NewLine)) continue; Statement s = ParseStmt(); l.Add(s); } Statement[] stmts = l.ToArray(); SuiteStatement ret = new SuiteStatement(stmts); Location start = new Location(); start.Column = start.Line = 1; ret.SetLoc(GetExternal(), start, GetEnd()); return ret; }