protected <T> boolean match( int bid, SequenceMatcher.MatchedStates<T> matchedStates, boolean consume) { if (consume) { Interval<Integer> matchedInterval = matchedStates.getBranchStates().getMatchedInterval(bid, this); int cur = matchedStates.curPosition; if (matchedInterval == null) { // Haven't tried to match this node before, try now // Get element and return if it matched or not List<? extends T> nodes = matchedStates.elements(); // TODO: Fix type checking Collection<Interval<Integer>> matched = pattern.match(nodes, cur); // TODO: Check intervals are valid? Start at cur and ends after? if (matched != null && matched.size() > 0) { int nBranches = matched.size(); int i = 0; for (Interval<Integer> interval : matched) { i++; int bid2 = matchedStates.getBranchStates().getBranchId(bid, i, nBranches); matchedStates.getBranchStates().setMatchedInterval(bid2, this, interval); // If matched, need to add next states to the queue of states to be processed // keep in current state until end node reached if (interval.getEnd() - 1 <= cur) { matchedStates.addStates(bid2, next); } else { matchedStates.addState(bid2, this); } } return true; } else { return false; } } else { // Previously matched this state - just need to step through until we get to end of // matched interval if (matchedInterval.getEnd() - 1 <= cur) { matchedStates.addStates(bid, next); } else { matchedStates.addState(bid, this); } return true; } } else { // Not consuming element - add this state back to queue of states to be processed // This state was not successfully matched matchedStates.addState(bid, this); return false; } }
protected <T> boolean match( int bid, SequenceMatcher.MatchedStates<T> matchedStates, SequenceMatcher.MatchedGroup matchedGroup, int matchedNodes) { T node = matchedStates.get(); if (matcher.matches( node, matchedStates.elements().get(matchedGroup.matchBegin + matchedNodes))) { matchedNodes++; matchedStates .getBranchStates() .setMatchStateInfo( bid, this, new Pair<SequenceMatcher.MatchedGroup, Integer>(matchedGroup, matchedNodes)); int len = matchedGroup.matchEnd - matchedGroup.matchBegin; if (len == matchedNodes) { matchedStates.addStates(bid, next); } else { matchedStates.addState(bid, this); } return true; } return false; }
protected <T> boolean match( int bid, SequenceMatcher.MatchedStates<T> matchedStates, boolean consume) { // We only mark start when about to consume elements if (consume) { // Start of group, mark start matchedStates.setGroupStart(bid, captureGroupId); return super.match(bid, matchedStates, consume); } else { // Not consuming, just add this state back to list of states to be processed matchedStates.addState(bid, this); return false; } }
protected <T> boolean match( int bid, SequenceMatcher.MatchedStates<T> matchedStates, boolean consume) { if (consume) { // Get element and return if it matched or not T node = matchedStates.get(); // TODO: Fix type checking if (pattern.match(node)) { // If matched, need to add next states to the queue of states to be processed matchedStates.addStates(bid, next); return true; } else { return false; } } else { // Not consuming element - add this state back to queue of states to be processed // This state was not successfully matched matchedStates.addState(bid, this); return false; } }
protected <T> boolean match( int bid, SequenceMatcher.MatchedStates<T> matchedStates, boolean consume) { // Try to match previous node/nodes exactly if (consume) { // First element is group that is matched, second is number of nodes matched so far Pair<SequenceMatcher.MatchedGroup, Integer> backRefState = (Pair<SequenceMatcher.MatchedGroup, Integer>) matchedStates.getBranchStates().getMatchStateInfo(bid, this); if (backRefState == null) { // Haven't tried to match this node before, try now // Get element and return if it matched or not SequenceMatcher.MatchedGroup matchedGroup = matchedStates.getBranchStates().getMatchedGroup(bid, captureGroupId); if (matchedGroup != null) { // See if the first node matches if (matchedGroup.matchEnd > matchedGroup.matchBegin) { boolean matched = match(bid, matchedStates, matchedGroup, 0); return matched; } else { // TODO: Check handling of previous nodes that are zero elements? return super.match(bid, matchedStates, consume); } } return false; } else { SequenceMatcher.MatchedGroup matchedGroup = backRefState.first(); int matchedNodes = backRefState.second(); boolean matched = match(bid, matchedStates, matchedGroup, matchedNodes); return matched; } } else { // Not consuming, just add this state back to list of states to be processed matchedStates.addState(bid, this); return false; } }
protected <T> boolean match( int bid, SequenceMatcher.MatchedStates<T> matchedStates, boolean consume) { // Get how many times this states has already been matched int matchedCount = matchedStates.getBranchStates().endMatchedCountInc(bid, this); // Get the minimum number of times we still need to match this state int minMatchLeft = minMatch - matchedCount; if (minMatchLeft < 0) { minMatchLeft = 0; } // Get the maximum number of times we can match this state int maxMatchLeft; if (maxMatch < 0) { // Indicate unlimited matching maxMatchLeft = maxMatch; } else { maxMatchLeft = maxMatch - matchedCount; if (maxMatch < 0) { // Already exceeded the maximum number of times we can match this state // indicate state not matched return false; } } boolean match = false; // See how many branching options there are... int totalBranches = 0; if (minMatchLeft == 0 && next != null) { totalBranches += next.size(); } if (maxMatchLeft != 0) { totalBranches++; } int i = 0; // branch index // Check if there we have met the minimum number of matches // If so, go ahead and try to match next state // (if we need to consume an element or end a group) if (minMatchLeft == 0 && next != null) { for (State s : next) { i++; // Increment branch index // Depending on greedy match or not, different priority to branches int pi = (greedyMatch && maxMatchLeft != 0) ? i + 1 : i; int bid2 = matchedStates.getBranchStates().getBranchId(bid, pi, totalBranches); matchedStates.getBranchStates().clearMatchedCount(bid2, this); boolean m = s.match(bid2, matchedStates, consume); if (m) { match = true; } } } // Check if we have the option of matching more // (maxMatchLeft < 0 indicate unlimited, maxMatchLeft > 0 indicate we are still allowed more // matches) if (maxMatchLeft != 0) { i++; // Increment branch index // Depending on greedy match or not, different priority to branches int pi = greedyMatch ? 1 : i; int bid2 = matchedStates.getBranchStates().getBranchId(bid, pi, totalBranches); if (consume) { // Consuming - try to see if repeating this pattern does anything boolean m = repeatStart.match(bid2, matchedStates, consume); if (m) { match = true; // Mark how many times we have matched this pattern matchedStates.getBranchStates().startMatchedCountInc(bid2, this); } } else { // Not consuming - don't do anything, just add this back to list of states to be processed matchedStates.addState(bid2, this); } } return match; }
protected <T> boolean match( int bid, SequenceMatcher.MatchedStates<T> matchedStates, boolean consume) { // Always add this state back (effectively looping forever in this matching state) matchedStates.addState(bid, this); return false; }