public boolean hasTransitions() { return isEndState() || !getOutgoing().isEmpty(); }
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; }
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; }
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); } }
@Override protected Node drawAbstractElementTree(AbstractElement grammarElement, Digraph digraph) { Node node = super.drawAbstractElementTree(grammarElement, digraph); MatcherState nfas = nfaProvider.getNFA(grammarElement); for (MatcherTransition outgoing : nfas.getOutgoing()) digraph.add(drawFollowerEdge(grammarElement, outgoing, false)); for (MatcherTransition outgoingAfterReturn : nfas.getOutgoingAfterReturn()) digraph.add(drawFollowerEdge(grammarElement, outgoingAfterReturn, true)); // for (MatcherTransition outgoingToNextRule : nfas.getOutgoingToNextRule()) // digraph.add(drawOutgoingToNextRuel(outgoingToNextRule)); if (nfas.isEndState()) node.put("peripheries", "2"); if (!nfas.hasTransitions()) node.setStyle("dotted"); return node; }