| Index: pkg/analyzer/lib/src/generated/parser.dart | 
| diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart | 
| index 33eba26d683875fa8ab9bdf729882c49f13f2e89..ea41c985f8a75d59658d1c4392f2600a62ac7507 100644 | 
| --- a/pkg/analyzer/lib/src/generated/parser.dart | 
| +++ b/pkg/analyzer/lib/src/generated/parser.dart | 
| @@ -170,6 +170,8 @@ class Parser { | 
|  | 
| static String _YIELD = Keyword.YIELD.syntax; | 
|  | 
| +  static const int _MAX_TREE_DEPTH = 300; | 
| + | 
| /** | 
| * The source being parsed. | 
| */ | 
| @@ -215,6 +217,12 @@ class Parser { | 
| Token _currentToken; | 
|  | 
| /** | 
| +   * The depth of the current AST. When this depth is too high, so we're at the | 
| +   * risk of overflowing the stack, we stop parsing and report an error. | 
| +   */ | 
| +  int _treeDepth = 0; | 
| + | 
| +  /** | 
| * A flag indicating whether the parser is currently in a function body marked | 
| * as being 'async'. | 
| */ | 
| @@ -1960,8 +1968,16 @@ class Parser { | 
| [_currentToken.lexeme]); | 
| _advance(); | 
| } else { | 
| -        CompilationUnitMember member = | 
| -            parseCompilationUnitMember(commentAndMetadata); | 
| +        CompilationUnitMember member; | 
| +        try { | 
| +          member = parseCompilationUnitMember(commentAndMetadata); | 
| +        } on _TooDeepTreeError { | 
| +          _reportErrorForToken(ParserErrorCode.STACK_OVERFLOW, _currentToken); | 
| +          Token eof = new Token(TokenType.EOF, 0); | 
| +          eof.previous = eof; | 
| +          eof.setNext(eof); | 
| +          return astFactory.compilationUnit(eof, null, null, null, eof); | 
| +        } | 
| if (member != null) { | 
| declarations.add(member); | 
| } | 
| @@ -2712,37 +2728,45 @@ class Parser { | 
| *       | throwExpression | 
| */ | 
| Expression parseExpression2() { | 
| -    Keyword keyword = _currentToken.keyword; | 
| -    if (keyword == Keyword.THROW) { | 
| -      return parseThrowExpression(); | 
| -    } else if (keyword == Keyword.RETHROW) { | 
| -      // TODO(brianwilkerson) Rethrow is a statement again. | 
| -      return parseRethrowExpression(); | 
| +    if (_treeDepth > _MAX_TREE_DEPTH) { | 
| +      throw new _TooDeepTreeError(); | 
| } | 
| -    // | 
| -    // assignableExpression is a subset of conditionalExpression, so we can | 
| -    // parse a conditional expression and then determine whether it is followed | 
| -    // by an assignmentOperator, checking for conformance to the restricted | 
| -    // grammar after making that determination. | 
| -    // | 
| -    Expression expression = parseConditionalExpression(); | 
| -    TokenType type = _currentToken.type; | 
| -    if (type == TokenType.PERIOD_PERIOD) { | 
| -      List<Expression> cascadeSections = <Expression>[]; | 
| -      do { | 
| -        Expression section = parseCascadeSection(); | 
| -        if (section != null) { | 
| -          cascadeSections.add(section); | 
| -        } | 
| -      } while (_currentToken.type == TokenType.PERIOD_PERIOD); | 
| -      return astFactory.cascadeExpression(expression, cascadeSections); | 
| -    } else if (type.isAssignmentOperator) { | 
| -      Token operator = getAndAdvance(); | 
| -      _ensureAssignable(expression); | 
| -      return astFactory.assignmentExpression( | 
| -          expression, operator, parseExpression2()); | 
| +    _treeDepth++; | 
| +    try { | 
| +      Keyword keyword = _currentToken.keyword; | 
| +      if (keyword == Keyword.THROW) { | 
| +        return parseThrowExpression(); | 
| +      } else if (keyword == Keyword.RETHROW) { | 
| +        // TODO(brianwilkerson) Rethrow is a statement again. | 
| +        return parseRethrowExpression(); | 
| +      } | 
| +      // | 
| +      // assignableExpression is a subset of conditionalExpression, so we can | 
| +      // parse a conditional expression and then determine whether it is followed | 
| +      // by an assignmentOperator, checking for conformance to the restricted | 
| +      // grammar after making that determination. | 
| +      // | 
| +      Expression expression = parseConditionalExpression(); | 
| +      TokenType type = _currentToken.type; | 
| +      if (type == TokenType.PERIOD_PERIOD) { | 
| +        List<Expression> cascadeSections = <Expression>[]; | 
| +        do { | 
| +          Expression section = parseCascadeSection(); | 
| +          if (section != null) { | 
| +            cascadeSections.add(section); | 
| +          } | 
| +        } while (_currentToken.type == TokenType.PERIOD_PERIOD); | 
| +        return astFactory.cascadeExpression(expression, cascadeSections); | 
| +      } else if (type.isAssignmentOperator) { | 
| +        Token operator = getAndAdvance(); | 
| +        _ensureAssignable(expression); | 
| +        return astFactory.assignmentExpression( | 
| +            expression, operator, parseExpression2()); | 
| +      } | 
| +      return expression; | 
| +    } finally { | 
| +      _treeDepth--; | 
| } | 
| -    return expression; | 
| } | 
|  | 
| /** | 
| @@ -4795,20 +4819,29 @@ class Parser { | 
| *         label* nonLabeledStatement | 
| */ | 
| Statement parseStatement2() { | 
| -    List<Label> labels = null; | 
| -    while (_matchesIdentifier() && _currentToken.next.type == TokenType.COLON) { | 
| -      Label label = parseLabel(isDeclaration: true); | 
| +    if (_treeDepth > _MAX_TREE_DEPTH) { | 
| +      throw new _TooDeepTreeError(); | 
| +    } | 
| +    _treeDepth++; | 
| +    try { | 
| +      List<Label> labels = null; | 
| +      while ( | 
| +          _matchesIdentifier() && _currentToken.next.type == TokenType.COLON) { | 
| +        Label label = parseLabel(isDeclaration: true); | 
| +        if (labels == null) { | 
| +          labels = <Label>[label]; | 
| +        } else { | 
| +          labels.add(label); | 
| +        } | 
| +      } | 
| +      Statement statement = parseNonLabeledStatement(); | 
| if (labels == null) { | 
| -        labels = <Label>[label]; | 
| -      } else { | 
| -        labels.add(label); | 
| +        return statement; | 
| } | 
| +      return astFactory.labeledStatement(labels, statement); | 
| +    } finally { | 
| +      _treeDepth--; | 
| } | 
| -    Statement statement = parseNonLabeledStatement(); | 
| -    if (labels == null) { | 
| -      return statement; | 
| -    } | 
| -    return astFactory.labeledStatement(labels, statement); | 
| } | 
|  | 
| /** | 
| @@ -8567,3 +8600,10 @@ class Parser { | 
| } | 
| } | 
| } | 
| + | 
| +/** | 
| + * Instances of this class are thrown when the parser detects that AST has | 
| + * too many nested expressions to be parsed safely and avoid possibility of | 
| + * [StackOverflowError] in the parser or during later analysis. | 
| + */ | 
| +class _TooDeepTreeError {} | 
|  |