in src/org/intellij/grammar/generator/ParserGenerator.java [530:606]
private void generateRootParserContent() {
BnfRule rootRule = myFile.getRule(myGrammarRoot);
List<BnfRule> extraRoots = new ArrayList<>();
for (String ruleName : myRuleInfos.keySet()) {
BnfRule rule = Objects.requireNonNull(myFile.getRule(ruleName));
if (getAttribute(rule, KnownAttribute.ELEMENT_TYPE) != null) continue;
if (!hasElementType(rule)) continue;
if (Rule.isFake(rule) || Rule.isMeta(rule)) continue;
ExpressionHelper.ExpressionInfo info = myExpressionHelper.getExpressionInfo(rule);
if (info != null && info.rootRule != rule) continue;
if (!Boolean.TRUE.equals(getAttribute(rule, KnownAttribute.EXTRA_ROOT))) continue;
extraRoots.add(rule);
}
List<Set<String>> extendsSet = buildExtendsSet(myGraphHelper.getRuleExtendsMap());
boolean generateExtendsSets = !extendsSet.isEmpty();
String shortET = shorten(C.IElementTypeClass);
String shortAN = shorten(C.AstNodeClass);
String shortPB = shorten(C.PsiBuilderClass);
String shortTS = shorten(C.TokenSetClass);
String shortMarker = !G.generateFQN ? "Marker" : C.PsiBuilderClass + ".Marker";
out("public %s parse(%s %s, %s %s) {", shortAN, shortET, N.root, shortPB, N.builder);
out("parseLight(%s, %s);", N.root, N.builder);
out("return %s.getTreeBuilt();", N.builder);
out("}");
newLine();
out("public void parseLight(%s %s, %s %s) {", shortET, N.root, shortPB, N.builder);
out("boolean %s;", N.result);
out("%s = adapt_builder_(%s, %s, this, %s);", N.builder, N.root, N.builder, generateExtendsSets ? "EXTENDS_SETS_" : null);
out("%s %s = enter_section_(%s, 0, _COLLAPSE_, null);", shortMarker, N.marker, N.builder);
out("%s = parse_root_(%s, %s);", N.result, N.root, N.builder);
out("exit_section_(%s, 0, %s, %s, %s, true, TRUE_CONDITION);", N.builder, N.marker, N.root, N.result);
out("}");
newLine();
out("protected boolean parse_root_(%s %s, %s %s) {", shortET, N.root, shortPB, N.builder);
out("return parse_root_(%s, %s, 0);", N.root, N.builder);
out("}");
newLine();
out("static boolean parse_root_(%s %s, %s %s, int %s) {", shortET, N.root, shortPB, N.builder, N.level);
if (extraRoots.isEmpty()) {
out("return %s;", rootRule == null ? "false" : generateNodeCall(rootRule, null, myGrammarRoot).render(N));
}
else {
boolean first = true;
out("boolean %s;", N.result);
for (BnfRule rule : extraRoots) {
String elementType = getElementType(rule);
out("%sif (%s == %s) {", first ? "" : "else ", N.root, elementType);
String nodeCall = generateNodeCall(ObjectUtils.notNull(rootRule, rule), null, rule.getName()).render(N);
out("%s = %s;", N.result, nodeCall);
out("}");
if (first) first = false;
}
out("else {");
out("%s = %s;", N.result, rootRule == null ? "false" : generateNodeCall(rootRule, null, myGrammarRoot).render(N));
out("}");
out("return %s;", N.result);
}
out("}");
newLine();
if (generateExtendsSets) {
out("public static final %s[] EXTENDS_SETS_ = new %s[] {", shortTS, shortTS);
StringBuilder sb = new StringBuilder();
for (Set<String> elementTypes : extendsSet) {
int i = 0;
for (String elementType : elementTypes) {
if (i > 0) sb.append(i % 4 == 0 ? ",\n" : ", ");
sb.append(elementType);
i++;
}
out("create_token_set_(%s),", sb);
sb.setLength(0);
}
out("};");
newLine();
}
}