in src/org/intellij/grammar/refactor/BnfExpressionOptimizer.java [25:75]
public static void optimize(@NotNull Project project, @NotNull PsiElement element) {
LinkedList<PsiElement> list = new LinkedList<>();
list.add(element.getParent());
list.add(element);
while (!list.isEmpty()) {
PsiElement cur = list.removeLast();
PsiElement parent = cur.getParent();
if (isTrivial(cur)) {
mergeChildrenTo(parent, cur, list);
}
else if (cur instanceof BnfParenOptExpression && isTrivialOrSingular(((BnfParenOptExpression)cur).getExpression())) {
// currently, <expr> + ? expressions are not supported, thus:
BnfExpression child = ((BnfParenOptExpression)cur).getExpression();
IElementType type = ParserGeneratorUtil.getEffectiveType(child);
if (type == BnfTypes.BNF_OP_OPT || type == BnfTypes.BNF_OP_ZEROMORE) {
list.add(cur.replace(child));
}
else if (type == BnfTypes.BNF_OP_ONEMORE) {
String replacement = ((BnfQuantified)child).getExpression().getText() + "*";
list.add(cur.replace(BnfElementFactory.createExpressionFromText(project, replacement)));
}
else {
String replacement = child.getText() + "?";
list.add(cur.replace(BnfElementFactory.createExpressionFromText(project, replacement)));
}
}
else if (cur instanceof BnfChoice &&
!(parent instanceof BnfParenthesized) &&
(parent instanceof BnfSequence || parent instanceof BnfQuantified)) {
String replacement = "(" + cur.getText() + ")";
cur.replace(BnfElementFactory.createExpressionFromText(project, replacement));
}
else if (isOptMany(cur) && isOptMany(PsiTreeUtil.getChildOfType(cur, BnfExpression.class))) {
BnfExpression child = PsiTreeUtil.getChildOfType(cur, BnfExpression.class);
IElementType type1 = ParserGeneratorUtil.getEffectiveType(cur);
IElementType type2 = ParserGeneratorUtil.getEffectiveType(child);
if (type1 == type2) {
list.add(cur.replace(child));
}
else if (type1 == BnfTypes.BNF_OP_OPT && type2 == BnfTypes.BNF_OP_ONEMORE ||
type2 == BnfTypes.BNF_OP_OPT && type1 == BnfTypes.BNF_OP_ONEMORE ||
type1 == BnfTypes.BNF_OP_ZEROMORE || type2 == BnfTypes.BNF_OP_ZEROMORE
) {
BnfExpression childOfChild = PsiTreeUtil.getChildOfType(child, BnfExpression.class);
String childText = childOfChild == null? "" : childOfChild.getText();
String replacement = (child instanceof BnfParenthesized? "(" + childText + ")" : childText) + "*";
cur.replace(BnfElementFactory.createExpressionFromText(project, replacement)); //
}
}
}
}