001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Nikolay Kuznetsov
020: * @version $Revision: 1.1 $
021: */package java.util.regex;
022:
023: /**
024: * Group node over subexpression w/o alternations.
025: * This node is used if current group is referenced
026: * via backreference.
027: */
028:
029: class BackReferencedSingleSet extends SingleSet {
030:
031: /*
032: * This class is needed only for overwriting find()
033: * and findBack() methods of SingleSet class, which is being
034: * back referenced. The following example explains the need
035: * for such substitution:
036: * Let's consider the pattern ".*(.)\\1".
037: * Leading .* works as follows: finds line terminator and runs findBack
038: * from that point. findBack method in its turn (in contrast to matches)
039: * sets group boundaries on the back trace. Thus at the point we
040: * try to match back reference(\\1) groups are not yet set.
041: *
042: * To fix this problem we replace backreferenced groups with instances of
043: * this class, which will use matches instead of find; this will affect
044: * performance, but ensure correctness of the match.
045: */
046:
047: public BackReferencedSingleSet(AbstractSet child, FSet fSet) {
048: super (child, fSet);
049: }
050:
051: public BackReferencedSingleSet(SingleSet node) {
052: super (node.kid, ((FSet) node.fSet));
053: }
054:
055: public int find(int stringIndex, CharSequence testString,
056: MatchResultImpl matchResult) {
057: int res = 0;
058: int lastIndex = matchResult.getRightBound();
059: int startSearch = stringIndex;
060:
061: for (; startSearch <= lastIndex; startSearch++) {
062: int saveStart = matchResult.getStart(groupIndex);
063:
064: matchResult.setStart(groupIndex, startSearch);
065: res = kid.matches(startSearch, testString, matchResult);
066: if (res >= 0) {
067: res = startSearch;
068: break;
069: } else {
070: matchResult.setStart(groupIndex, saveStart);
071: }
072: }
073:
074: return res;
075: }
076:
077: public int findBack(int stringIndex, int lastIndex,
078: CharSequence testString, MatchResultImpl matchResult) {
079: int res = 0;
080: int startSearch = lastIndex;
081:
082: for (; startSearch >= stringIndex; startSearch--) {
083: int saveStart = matchResult.getStart(groupIndex);
084:
085: matchResult.setStart(groupIndex, startSearch);
086: res = kid.matches(startSearch, testString, matchResult);
087: if (res >= 0) {
088: res = startSearch;
089: break;
090: } else {
091: matchResult.setStart(groupIndex, saveStart);
092: }
093: }
094:
095: return res;
096: }
097:
098: /**
099: * This method is used for replacement backreferenced
100: * sets.
101: *
102: * @param prev - node who references to this node
103: */
104: public JointSet processBackRefReplacement() {
105: return null;
106: }
107: }
|