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;
}