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; }
else if (transition.getTarget().isParserRuleCall()) { ruleCallStack.push(transition.getTarget()); Pair<List<MatcherTransition>, List<MatcherState>> next = findTransitionPath( transition.getTarget(), to, false, transition.getTarget().isParserRuleCallOptional(), visited); Pair<List<MatcherTransition>, List<MatcherState>> next = findTransitionPath(lastRuleCall, to, true, true, visited); if (next != null) {
protected List<MatcherTransition> findTransitionsToToken(MatcherState from, Set<MatcherState> targets, boolean returning, boolean canReturn, Set<MatcherState> visited) { if (!visited.add(from)) return Collections.emptyList(); if (targets != null && targets.contains(from)) targets = null; List<MatcherTransition> result = Lists.newArrayList(); for (MatcherTransition transition : returning ? from.getOutgoingAfterReturn() : from.getOutgoing()) { if (transition.getTarget().isParserRuleCall()) result.addAll(findTransitionsToToken(transition.getTarget(), targets, false, transition.getTarget() .isParserRuleCallOptional(), visited)); else if (targets == null || targets.contains(transition.getTarget())) result.add(transition); } if (canReturn && from.isEndState()) for (MatcherState caller : findRuleCallsTo(GrammarUtil.containingRule(from.getGrammarElement()), Sets.<AbstractRule> newHashSet())) result.addAll(findTransitionsToToken(caller, targets, true, true, visited)); return result; }
@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 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 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); } }
public <T extends IElementPattern> IElementMatcher<T> createMatcher(Iterable<T> rules) { return new TransitionMatcher<T>(grammar, nfaProvider, rules); }
public Collection<T> matchNext(AbstractElement nextElement) { Pair<List<MatcherTransition>, List<MatcherState>> path = findTransitionPath(lastState, nextElement, false, true, Sets.<Pair<Boolean, MatcherState>> newHashSet()); if (path == null) { MatcherState previousState = lastState; lastState = nfaProvider.getNFA(nextElement); // System.out.println("Not Found! looking for " + new GrammarElementTitleSwitch().doSwitch(nextElement)); return patternsForTwoStates(previousState, lastState); } else { // System.out.println("Found " + path + " -> " + patternsForTransition(path)); lastState = path.getFirst().get(path.getFirst().size() - 1).getTarget(); return patternsForTransition(path); } }
protected void installBetween(IBetweenElements pattern) { if (pattern.matchBetween().getFirst() == pattern.matchBetween().getSecond()) installBetween(pattern, pattern.matchBetween().getFirst()); else installBetween(pattern, pattern.matchBetween().getFirst(), pattern.matchBetween().getSecond()); }
public TransitionMatcher(IGrammarAccess grammar, MatcherNFAProvider nfaProvider, Iterable<T> patterns) { super(); this.grammar = grammar; this.nfaProvider = nfaProvider; installAllPatterns(patterns); }
@Override @SuppressWarnings({ "unchecked" }) protected Props drawObject(Object obj) { if (obj == null) throw new NullPointerException("Obj null"); if (obj instanceof TransitionMatcher) { TransitionMatcher<IElementMatcherProvider.IElementPattern> m = (TransitionMatcher<IElementMatcherProvider.IElementPattern>) obj; nfaProvider = m.nfaProvider; return super.drawObject(m.getGrammar().getGrammar()); } return super.drawObject(obj); }
protected void installAllPatterns(Iterable<T> patterns) { for (IElementPattern pattern : patterns) { if (pattern instanceof IBeforeElement && ((IBeforeElement) pattern).matchBefore() != null) installBefore((IBeforeElement) pattern); if (pattern instanceof IAfterElement && ((IAfterElement) pattern).matchAfter() != null) installAfter((IAfterElement) pattern); if (pattern instanceof IBetweenElements && ((IBetweenElements) pattern).matchBetween() != null) installBetween((IBetweenElements) pattern); } }
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); } }
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); } }