public static boolean parseAsTree()

in src/org/intellij/grammar/parser/GeneratedParserUtilBase.java [1152:1229]


  public static boolean parseAsTree(ErrorState state, PsiBuilder builder, int level,
                                    IElementType chunkType, boolean checkBraces,
                                    Parser parser, Parser eatMoreCondition) {
    ArrayDeque<Pair<PsiBuilder.Marker, PsiBuilder.Marker>> parens = new ArrayDeque<>(4);
    ArrayDeque<Pair<PsiBuilder.Marker, Integer>> siblings = new ArrayDeque<>();
    PsiBuilder.Marker marker = null;

    IElementType lBrace = checkBraces && state.braces != null && state.braces.length > 0 ? state.braces[0].getLeftBraceType() : null;
    IElementType rBrace = lBrace != null ? state.braces[0].getRightBraceType() : null;
    int totalCount = 0;
    int tokenCount = 0;
    if (lBrace != null) {
      int tokenIdx = -1;
      while (builder.rawLookup(tokenIdx) == TokenType.WHITE_SPACE) tokenIdx --;
      LighterASTNode doneMarker = builder.rawLookup(tokenIdx) == lBrace ? builder.getLatestDoneMarker() : null;
      if (doneMarker != null && doneMarker.getStartOffset() == builder.rawTokenTypeStart(tokenIdx) && doneMarker.getTokenType() == TokenType.ERROR_ELEMENT) {
        parens.add(Pair.create(((PsiBuilder.Marker)doneMarker).precede(), null));
      }
    }
    int c = current_position_(builder);
    while (true) {
      IElementType tokenType = builder.getTokenType();
      if (lBrace != null && (tokenType == lBrace || tokenType == rBrace && !parens.isEmpty())) {
        if (marker != null) {
          marker.done(chunkType);
          siblings.addFirst(Pair.create(marker, 1));
          marker = null;
          tokenCount = 0;
        }
        if (tokenType == lBrace) {
          Pair<PsiBuilder.Marker, Integer> prev = siblings.peek();
          parens.addFirst(Pair.create(builder.mark(), Pair.getFirst(prev)));
        }
        checkSiblings(chunkType, parens, siblings);
        state.tokenAdvancer.parse(builder, level);
        if (tokenType == rBrace) {
          Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair = parens.removeFirst();
          pair.first.done(chunkType);
          // drop all markers inside parens
          while (!siblings.isEmpty() && siblings.getFirst().first != pair.second) {
            siblings.removeFirst();
          }
          siblings.addFirst(Pair.create(pair.first, 1));
          checkSiblings(chunkType, parens, siblings);
        }
      }
      else {
        if (marker == null) {
          marker = builder.mark();
          marker.setCustomEdgeTokenBinders(WhitespacesBinders.GREEDY_LEFT_BINDER, null);
        }
        boolean result = (!parens.isEmpty() || eatMoreCondition.parse(builder, level + 1)) &&
                         parser.parse(builder, level + 1);
        if (result) {
          tokenCount++;
          totalCount++;
        }
        else {
          break;
        }
      }

      if (tokenCount >= MAX_CHILDREN_IN_TREE) {
        marker.done(chunkType);
        siblings.addFirst(Pair.create(marker, 1));
        checkSiblings(chunkType, parens, siblings);
        marker = null;
        tokenCount = 0;
      }
      if (!empty_element_parsed_guard_(builder, "parseAsTree", c)) break;
      c = current_position_(builder);
    }
    if (marker != null) marker.drop();
    for (Pair<PsiBuilder.Marker, PsiBuilder.Marker> pair : parens) {
      pair.first.drop();
    }
    return totalCount != 0;
  }