void () { assertCurrentToken(PyTokenTypes.TRY_KEYWORD); final SyntaxTreeBuilder.Marker statement = myBuilder.mark(); final SyntaxTreeBuilder.Marker tryPart = myBuilder.mark(); myBuilder.advanceLexer(); parseColonAndSuite(); tryPart.done(PyElementTypes.TRY_PART); boolean haveExceptClause = false; if (myBuilder.getTokenType() == PyTokenTypes.EXCEPT_KEYWORD) { haveExceptClause = true; while (myBuilder.getTokenType() == PyTokenTypes.EXCEPT_KEYWORD) { final SyntaxTreeBuilder.Marker exceptBlock = myBuilder.mark(); myBuilder.advanceLexer(); boolean star = matchToken(PyTokenTypes.MULT); if (myBuilder.getTokenType() != PyTokenTypes.COLON) { if (!getExpressionParser().parseSingleExpression(false)) { myBuilder.error(PyParsingBundle.message("PARSE.expected.expression")); } if (myBuilder.getTokenType() == PyTokenTypes.COMMA || myBuilder.getTokenType() == PyTokenTypes.AS_KEYWORD) { myBuilder.advanceLexer(); if (!getExpressionParser().parseSingleExpression(true)) { myBuilder.error(PyParsingBundle.message("PARSE.expected.expression")); } } } else if (star) { myBuilder.error(PyParsingBundle.message("PARSE.expected.expression")); } parseColonAndSuite(); exceptBlock.done(PyElementTypes.EXCEPT_PART); } final SyntaxTreeBuilder.Marker elsePart = myBuilder.mark(); if (myBuilder.getTokenType() == PyTokenTypes.ELSE_KEYWORD) { myBuilder.advanceLexer(); parseColonAndSuite(); elsePart.done(PyElementTypes.ELSE_PART); } else { elsePart.drop(); } } final SyntaxTreeBuilder.Marker finallyPart = myBuilder.mark(); if (myBuilder.getTokenType() == PyTokenTypes.FINALLY_KEYWORD) { myBuilder.advanceLexer(); parseColonAndSuite(); finallyPart.done(PyElementTypes.FINALLY_PART); } else { finallyPart.drop(); if (!haveExceptClause) { myBuilder.error(PyParsingBundle.message("except.or.finally.expected")); // much better to have a statement of incorrectly determined type // than "TRY" and "COLON" tokens attached to nothing } } statement.done(PyElementTypes.TRY_EXCEPT_STATEMENT); }