@Override protected MatcherState createState(AbstractElement grammarElement) { return new MatcherState(grammarElement, this); }
/** * @since 2.0 */ public List<MatcherTransition> collectOutgoingTransitions() { outgoing = Lists.newArrayList(); outgoingRuleCalls = Lists.newArrayList(); collectOutgoing(element, Sets.<AbstractElement> newHashSet(), false, null); removeDuplicates(outgoing); removeDuplicates(outgoingRuleCalls); return outgoingRuleCalls.isEmpty() ? outgoing : outgoingRuleCalls; }
protected void installBetween(IBetweenElements pattern, AbstractElement loopCenter) { Set<MatcherState> states = getAllStates(loopCenter); for (MatcherState state : states) { state.getBeforeBetweenElements().add(pattern); state.getAfterBetweenElements().add(pattern); for (MatcherTransition transition : state.getAllOutgoing()) if (transition.getLoopCenter() == loopCenter && states.contains(transition.getTarget())) transition.addPattern(pattern); } }
if (from != null) { List<MatcherTransition> transitions; if (from.getAllOutgoing().isEmpty()) transitions = from.collectOutgoingTransitions(); else transitions = returning ? from.getOutgoingAfterReturn() : from.getOutgoing(); for (MatcherTransition transition : transitions) { if (transition.getTarget().getGrammarElement() == to) return Tuples.create(Collections.singletonList(transition), Collections.singletonList(from)); else if (transition.getTarget().isParserRuleCall()) { ruleCallStack.push(transition.getTarget()); Pair<List<MatcherTransition>, List<MatcherState>> next = findTransitionPath( transition.getTarget(), to, false, transition.getTarget().isParserRuleCallOptional(), visited); if (next != null) { if (canReturn && from.isEndState() && !ruleCallStack.isEmpty()) { MatcherState lastRuleCall = ruleCallStack.pop(); Pair<List<MatcherTransition>, List<MatcherState>> next = findTransitionPath(lastRuleCall, to, true,
protected void installAfter(IAfterElement pattern) { Set<MatcherState> states = getAllStates(pattern.matchAfter()); AbstractRule rule = GrammarUtil.containingRule(pattern.matchAfter()); for (MatcherState state : states) { state.getAfterPatterns().add(pattern); for (MatcherTransition out : state.isParserRuleCall() ? state.getOutgoingAfterReturn() : state .getOutgoing()) if (pattern.matchAfter() == out.getLoopCenter() || !states.contains(out.getTarget())) out.addPattern(pattern); if (state.isEndState()) for (MatcherState caller : findRuleCallsTo(rule, Sets.<AbstractRule> newHashSet())) for (MatcherTransition afterReturn : caller.getOutgoingAfterReturn()) afterReturn.addPattern(state, pattern); } }
@SuppressWarnings("unchecked") protected Collection<T> patternsForTwoStates(MatcherState first, MatcherState second) { Collection<IElementPattern> result = Sets.newHashSet(); if (first != null) { result.addAll(first.getAfterPatterns()); for (IBetweenElements between : first.getAfterBetweenElements()) if (getAllStates(between.matchBetween().getSecond()).contains(second)) result.add(between); for (IBetweenElements between : second.getBeforeBetweenElements()) if (getAllStates(between.matchBetween().getFirst()).contains(first)) result.add(between); } result.addAll(second.getBeforePatterns()); return (Collection<T>) result; } }
protected Set<MatcherState> findRuleCallsTo(AbstractRule rule, Set<AbstractRule> visited) { if (!visited.add(rule)) return Collections.emptySet(); Set<MatcherState> result = Sets.newHashSet(); Iterator<EObject> i = rule.eAllContents(); while (i.hasNext()) { EObject obj = i.next(); if (obj instanceof AbstractElement) { MatcherState state = nfaProvider.getNFA((AbstractElement) obj); if (state.hasTransitions()) for (MatcherTransition incoming : state.getAllIncoming()) if (incoming.isRuleCall() && result.add(incoming.getSource()) && incoming.getSource().isEndState()) result.addAll(findRuleCallsTo( GrammarUtil.containingRule(incoming.getSource().getGrammarElement()), visited)); } } return result; }
protected void installBetween(IBetweenElements pattern, AbstractElement first, AbstractElement second) { Set<MatcherState> sources = getAllStates(first); Set<MatcherState> targets = getAllStates(second); for (MatcherState target : targets) target.getBeforeBetweenElements().add(pattern); for (MatcherState source : sources) { source.getAfterBetweenElements().add(pattern); for (MatcherTransition transition : findTransitionsToToken(source, targets, source.isParserRuleCall(), true, Sets.<MatcherState> newHashSet())) { if (transition.getSource() == source) transition.addPattern(pattern); else transition.addPattern(source, pattern); } } }
protected boolean isOptional(AbstractElement ele) { if (GrammarUtil.isOptionalCardinality(ele) || ele instanceof Action) return true; if (ele instanceof CompoundElement) { List<EObject> children = ele.eContents(); if (children.isEmpty() && getBuilder().filter(ele)) return true; if (ele instanceof Alternatives) { for (AbstractElement a : ((Alternatives) ele).getElements()) if (isOptional(a)) return true; return false; } for (EObject e : children) if (e instanceof AbstractElement && !isOptional((AbstractElement) e)) return false; return true; } else return false; }
protected void installBefore(IBeforeElement pattern) { Set<MatcherState> states = getAllStates(pattern.matchBefore()); for (MatcherState state : states) { state.getBeforePatterns().add(pattern); for (MatcherTransition incoming : state.getAllIncoming()) if (pattern.matchBefore() == incoming.getLoopCenter() || !states.contains(incoming.getSource())) incoming.addPattern(pattern); } }
@SuppressWarnings("unchecked") public Collection<T> finish() { if (lastState != null) { List<IElementPattern> result = Lists.<IElementPattern> newArrayList(lastState.getAfterPatterns()); while (!ruleCallStack.isEmpty()) result.addAll(ruleCallStack.pop().getAfterPatterns()); // String file = lastState.getGrammarElement().eResource().getURI().lastSegment() + "3.pdf"; // try { // new ElementMatcherToDot().draw(this, file, "-T pdf"); // } catch (IOException e) { // e.printStackTrace(); // } lastState = null; return (Collection<T>) result; } else return Collections.emptyList(); }