protected <T> boolean areAlternativeMultiples(StateAlias<T> first, StateAlias<T> second) { if (!first.getElement().isMany() || !second.getElement().isMany()) return false; if (!first.getOutgoing().contains(second) || !first.getIncoming().contains(second)) return false; for (StateAlias<T> in : first.getIncoming()) { if (!in.equals(second) && !second.getIncoming().contains(in)) return false; } for (StateAlias<T> out : first.getOutgoing()) { if (!out.equals(second) && !second.getOutgoing().contains(out)) return false; } return true; }
protected <T> boolean mergeOptionalIntoMany(StateAlias<T> state, Set<StateAlias<T>> visited) { if (!visited.add(state)) return false; boolean merged = false; if (state.getElement().isMany()) { for (StateAlias<T> out : ImmutableList.copyOf(state.getOutgoing())) { if (state.getIncoming().contains(out) && isOptionalIgnoring(out, state)) { mergeOptionalIntoMany(state, out); merged = true; } } for (StateAlias<T> in : ImmutableList.copyOf(state.getIncoming())) { if (state.getOutgoing().contains(in) && isOptionalIgnoring(in, state)) { mergeOptionalIntoMany(in, state); merged = true; } } } for (StateAlias<T> out : ImmutableList.copyOf(state.getOutgoing())) { if (mergeOptionalIntoMany(out, visited)) merged = true; } return merged; }
protected <T> boolean collectMergeableOptions(boolean root, AbstractElementAlias<T> alt, List<AbstractElementAlias<T>> result) { boolean optional = alt.optional; if ((root || !alt.isMany()) && alt instanceof AlternativeAlias<?>) { for (AbstractElementAlias<T> child : ((AlternativeAlias<T>) alt).getChildren()) optional |= collectMergeableOptions(false, child, result); } else { result.add(alt); alt.optional = false; } return optional; }
protected <T> void mergeOptionalIntoMany(StateAlias<T> first, StateAlias<T> second) { StateAlias<T> many = first.element.isMany() ? first : second; StateAlias<T> optional = many == first ? second : first; if (optional.getOutgoing().contains(optional)) { optional.element.setMany(true); } many.element.setMany(false); optional.element.setOptional(true); for (StateAlias<T> out : optional.getOutgoing()) { out.getIncoming().remove(optional); } for (StateAlias<T> in : optional.getIncoming()) { in.getOutgoing().remove(optional); } GroupAlias<T> group = new GroupAlias<T>(); group.setMany(true); if (first.element instanceof GroupAlias<?> && !first.element.many && !first.element.optional) { group.children.addAll(((GroupAlias<T>) first.element).children); } else { group.addChild(first.getElement()); } if (second.element instanceof GroupAlias<?> && !second.element.many && !second.element.optional) { group.children.addAll(((GroupAlias<T>) second.element).children); } else { group.addChild(second.element); } many.element = group; }
protected <T> boolean mergeAlternativeMultiples(StateAlias<T> state, Set<StateAlias<T>> visited) { if (!visited.add(state)) return false; boolean merged = false; if (state.getElement().isMany()) { for (StateAlias<T> out : ImmutableList.copyOf(state.getOutgoing())) { if (areAlternativeMultiples(state, out)) { mergeAlternativeMultiples(state, out); merged = true; } } } for (StateAlias<T> out : ImmutableList.copyOf(state.getOutgoing())) { if (mergeAlternativeMultiples(out, visited)) merged = true; } return merged; }
public boolean isMany(AbstractElementAlias<TOKEN> ele) { return ele.isMany(); }
@Override public boolean isMany(AbstractElementAlias<TOKEN> ele) { return ele.isMany(); }