private static final ConsumeType CONSUME_TYPE_OVERRIDE = ConsumeType.SMART;
public static void generateExpressionRoot(ExpressionHelper.ExpressionInfo info, ParserGenerator g) {
Map<String, List<OperatorInfo>> opCalls = ContainerUtil.newLinkedHashMap();
for (BnfRule rule : info.priorityMap.keySet()) {
OperatorInfo operator = info.operatorMap.get(rule);
String opCall = g.generateNodeCall(info.rootRule, operator.operator, getNextName(operator.rule.getName(), 0), CONSUME_TYPE_OVERRIDE);
List<OperatorInfo> list = opCalls.get(opCall);
if (list == null) opCalls.put(opCall, list = ContainerUtil.newArrayListWithCapacity(2));
list.add(operator);
}
Set<String> sortedOpCalls = opCalls.keySet();
for (String s : info.toString().split("\n")) {
g.out("// " + s);
}
// main entry
String methodName = info.rootRule.getName();
String kernelMethodName = getNextName(methodName, 0);
String frameName = quote(ParserGeneratorUtil.getRuleDisplayName(info.rootRule, true));
g.out("public static boolean %s(PsiBuilder %s, int %s, int %s) {", methodName, g.N.builder, g.N.level, g.N.priority);
g.out("if (!recursion_guard_(%s, %s, \"%s\")) return false;", g.N.builder, g.N.level, methodName);
if (frameName != null) {
g.out("addVariant(%s, %s);", g.N.builder, frameName);
}
g.generateFirstCheck(info.rootRule, frameName, true);
g.out("boolean %s, %s;", g.N.result, g.N.pinned);
g.out("Marker %s = enter_section_(%s, %s, _NONE_, %s);", g.N.marker, g.N.builder, g.N.level, frameName);
boolean first = true;
for (String opCall : sortedOpCalls) {
OperatorInfo operator = ContainerUtil.getFirstItem(findOperators(opCalls.get(opCall), OperatorType.ATOM, OperatorType.PREFIX));
if (operator == null) continue;
String nodeCall = g.generateNodeCall(operator.rule, null, operator.rule.getName());
g.out("%s%s = %s;", first ? "" : format("if (!%s) ", g.N.result), g.N.result, nodeCall);
first = false;
}
g.out("%s = %s;", g.N.pinned, g.N.result);
g.out("%s = %s && %s(%s, %s + 1, %s);", g.N.result, g.N.result, kernelMethodName, g.N.builder, g.N.level, g.N.priority);
g.out("exit_section_(%s, %s, %s, null, %s, %s, null);", g.N.builder, g.N.level, g.N.marker, g.N.result, g.N.pinned);
g.out("return %s || %s;", g.N.result, g.N.pinned);
g.out("}");
g.newLine();
// kernel
g.out("public static boolean %s(PsiBuilder %s, int %s, int %s) {", kernelMethodName, g.N.builder, g.N.level, g.N.priority);
g.out("if (!recursion_guard_(%s, %s, \"%s\")) return false;", g.N.builder, g.N.level, kernelMethodName);
g.out("boolean %s = true;", g.N.result);
g.out("while (true) {");
g.out("Marker %s = enter_section_(%s, %s, _LEFT_, null);", g.N.marker, g.N.builder, g.N.level);
first = true;
for (String opCall : sortedOpCalls) {
OperatorInfo operator =
ContainerUtil.getFirstItem(findOperators(opCalls.get(opCall), OperatorType.BINARY, OperatorType.N_ARY, OperatorType.POSTFIX));
if (operator == null) continue;
int priority = info.getPriority(operator.rule);
int arg2Priority = operator.arg2 == null ? -1 : info.getPriority(operator.arg2);
int argPriority = arg2Priority == -1 ? priority : arg2Priority - 1;