You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2006/04/19 09:50:13 UTC
svn commit: r395158 [1/3] - in
/incubator/harmony/enhanced/classlib/trunk/modules/regex/src:
main/java/java/util/regex/
test/java/org/apache/harmony/tests/java/util/regex/
Author: mloenko
Date: Wed Apr 19 00:50:10 2006
New Revision: 395158
URL: http://svn.apache.org/viewcvs?rev=395158&view=rev
Log:
fixes for HARMONY-350:
HARMONY-39 Regular expressions does not match backreferences during find.
Added:
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/BackReferencedSingleSet.java
Modified:
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/AbstractSet.java
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/FSet.java
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/JointSet.java
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/Lexer.java
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/Pattern.java
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/QuantifierSet.java
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/SingleSet.java
incubator/harmony/enhanced/classlib/trunk/modules/regex/src/test/java/org/apache/harmony/tests/java/util/regex/PatternTest.java
Modified: incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/AbstractSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/AbstractSet.java?rev=395158&r1=395157&r2=395158&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/AbstractSet.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/AbstractSet.java Wed Apr 19 00:50:10 2006
@@ -1,196 +1,260 @@
-/*
- * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Nikolay A. Kuznetsov
- * @version $Revision: 1.12.2.2 $
- */
-package java.util.regex;
-
-/**
- * Basic class for nodes, representing given regular expression.
- * Note: All the classes representing nodes has set prefix;
- *
- * @author Nikolay A. Kuznetsov
- * @version $Revision: 1.12.2.2 $
- */
-abstract class AbstractSet {
-
- public static final int TYPE_LEAF = 1 << 0;
-
- public static final int TYPE_FSET = 1 << 1;
-
- public static final int TYPE_QUANT = 1 << 3;
-
- public static final int TYPE_DOTSET = 0x80000000 | '.';
-
- /**
- * Next node to visit
- */
- protected AbstractSet next;
-
- /**
- * Counter for debugging purposes, represent unique node index;
- */
- static int counter = 1;
-
- protected String index = new Integer(AbstractSet.counter++).toString();
-
- private int type = 0;
-
- public AbstractSet() {
- }
-
- public AbstractSet(AbstractSet n) {
- next = n;
- }
-
- /**
- * Checks if this node matches in given position and requrcively call
- * next node matches on positive self match. Returns positive integer if
- * entire match succeed, negative otherwise
- * @param stringIndex - string index to start from;
- * @param testString - input string
- * @param matchResult - MatchResult to sore result into
- * @return -1 if match fails or n > 0;
- */
- public abstract int matches(int stringIndex, CharSequence testString,
- MatchResultImpl matchResult);
-
- /**
- * Attempts to apply pattern starting from this set/stringIndex; returns
- * index this search was started from, if value is negative, this means that
- * this search didn't succeed, additional information could be obtained via
- * matchResult;
- *
- * Note: this is default implementation for find method, it's based on
- * matches, subclasses do not have to override find method unless
- * more effective find method exists for a particular node type
- * (sequence, i.e. substring, for example). Same applies for find back
- * method.
- *
- * @param stringIndex
- * starting index
- * @param testString
- * string to search in
- * @param matchResult
- * result of the match
- * @return last searched index
- */
- public int find(int stringIndex, CharSequence testString,
- MatchResultImpl matchResult) {
- int length = matchResult.getRightBound();
- while (stringIndex <= length) {
- if (matches(stringIndex, testString, matchResult) >= 0) {
- return stringIndex;
- } else {
- stringIndex++;
- }
- }
- return -1;
- }
-
- /**
- * @param stringIndex -
- * an index, to finish search back (left limit)
- * @param startSearch -
- * an index to start search from (right limit)
- * @param testString -
- * test string;
- * @param matchResult
- * match result
- * @return an index to start back search next time if this search fails(new
- * left bound); if this search fails the value is negative;
- */
- public int findBack(int stringIndex, int startSearch,
- CharSequence testString, MatchResultImpl matchResult) {
- int shift;
- while (startSearch >= stringIndex) {
- if (matches(startSearch, testString, matchResult) >= 0) {
- return startSearch;
- } else {
- startSearch--;
- }
- }
- return -1;
- }
-
- /**
- * Returns true, if this node has consumed any characters during
- * positive match attempt, for example node representing character always
- * consumes one character if it matches. If particular node matches
- * empty sting this method will return false;
- *
- * @param matchResult
- * @return
- */
- public abstract boolean hasConsumed(MatchResultImpl matchResult);
-
- /**
- * Returns name for the particular node type.
- * Used for debugging purposes.
- */
- protected abstract String getName();
-
- protected void setType(int type) {
- this.type = type;
- }
-
- public int getType() {
- return this.type;
- }
-
- protected String getQualifiedName() {
- return "<" + index + ":" + getName() + ">";
- }
-
- public String toString() {
- return getQualifiedName();
- }
-
- /**
- * Returns the next.
- */
- public AbstractSet getNext() {
- return next;
- }
-
- /**
- * Sets next abstract set
- * @param next
- * The next to set.
- */
- public void setNext(AbstractSet next) {
- this.next = next;
- }
-
- /**
- * Returns true if the given node intersects with this one,
- * false otherwise.
- * This method is bieng used for quantifiers construction,
- * lets consider the following regular expression (a|b)*ccc.
- *
- * (a|b) does not intersects with "ccc" and thus can be quantified
- * greedly (w/o kickbacks), like *+ instead of *.
- *
- * @param set - usually previous node
- *
- * @return true if the given node intersects with this one
- */
- public boolean first(AbstractSet set) {
- return true;
- }
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Basic class for nodes, representing given regular expression.
+ * Note: All the classes representing nodes has set prefix;
+ *
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+abstract class AbstractSet {
+
+ public static final int TYPE_LEAF = 1 << 0;
+
+ public static final int TYPE_FSET = 1 << 1;
+
+ public static final int TYPE_QUANT = 1 << 3;
+
+ public static final int TYPE_DOTSET = 0x80000000 | '.';
+
+ /**
+ * Next node to visit
+ */
+ protected AbstractSet next;
+
+ /**
+ * Counter for debugging purposes, represent unique node index;
+ */
+ static int counter = 1;
+
+ protected boolean isSecondPassVisited = false;
+
+ protected String index = new Integer(AbstractSet.counter++).toString();
+
+ private int type = 0;
+
+ public AbstractSet() {
+ }
+
+ public AbstractSet(AbstractSet n) {
+ next = n;
+ }
+
+ /**
+ * Checks if this node matches in given position and requrcively call
+ * next node matches on positive self match. Returns positive integer if
+ * entire match succeed, negative otherwise
+ * @param stringIndex - string index to start from;
+ * @param testString - input string
+ * @param matchResult - MatchResult to sore result into
+ * @return -1 if match fails or n > 0;
+ */
+ public abstract int matches(int stringIndex, CharSequence testString,
+ MatchResultImpl matchResult);
+
+ /**
+ * Attempts to apply pattern starting from this set/stringIndex; returns
+ * index this search was started from, if value is negative, this means that
+ * this search didn't succeed, additional information could be obtained via
+ * matchResult;
+ *
+ * Note: this is default implementation for find method, it's based on
+ * matches, subclasses do not have to override find method unless
+ * more effective find method exists for a particular node type
+ * (sequence, i.e. substring, for example). Same applies for find back
+ * method.
+ *
+ * @param stringIndex
+ * starting index
+ * @param testString
+ * string to search in
+ * @param matchResult
+ * result of the match
+ * @return last searched index
+ */
+ public int find(int stringIndex, CharSequence testString,
+ MatchResultImpl matchResult) {
+ int length = matchResult.getRightBound();
+ while (stringIndex <= length) {
+ if (matches(stringIndex, testString, matchResult) >= 0) {
+ return stringIndex;
+ } else {
+ stringIndex++;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * @param stringIndex -
+ * an index, to finish search back (left limit)
+ * @param startSearch -
+ * an index to start search from (right limit)
+ * @param testString -
+ * test string;
+ * @param matchResult
+ * match result
+ * @return an index to start back search next time if this search fails(new
+ * left bound); if this search fails the value is negative;
+ */
+ public int findBack(int stringIndex, int startSearch,
+ CharSequence testString, MatchResultImpl matchResult) {
+ int shift;
+ while (startSearch >= stringIndex) {
+ if (matches(startSearch, testString, matchResult) >= 0) {
+ return startSearch;
+ } else {
+ startSearch--;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Returns true, if this node has consumed any characters during
+ * positive match attempt, for example node representing character always
+ * consumes one character if it matches. If particular node matches
+ * empty sting this method will return false;
+ *
+ * @param matchResult
+ * @return
+ */
+ public abstract boolean hasConsumed(MatchResultImpl matchResult);
+
+ /**
+ * Returns name for the particular node type.
+ * Used for debugging purposes.
+ */
+ protected abstract String getName();
+
+ protected void setType(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return this.type;
+ }
+
+ protected String getQualifiedName() {
+ return "<" + index + ":" + getName() + ">";
+ }
+
+ public String toString() {
+ return getQualifiedName();
+ }
+
+ /**
+ * Returns the next.
+ */
+ public AbstractSet getNext() {
+ return next;
+ }
+
+ /**
+ * Sets next abstract set
+ * @param next
+ * The next to set.
+ */
+ public void setNext(AbstractSet next) {
+ this.next = next;
+ }
+
+ /**
+ * Returns true if the given node intersects with this one,
+ * false otherwise.
+ * This method is bieng used for quantifiers construction,
+ * lets consider the following regular expression (a|b)*ccc.
+ *
+ * (a|b) does not intersects with "ccc" and thus can be quantified
+ * greedly (w/o kickbacks), like *+ instead of *.
+ *
+ * @param set - usually previous node
+ *
+ * @return true if the given node intersects with this one
+ */
+ public boolean first(AbstractSet set) {
+ return true;
+ }
+
+ /**
+ * This method is used for replacement backreferenced
+ * sets.
+ *
+ * @param prev - node who references to this node
+ * @return null if current node need not to be replaced
+ * JointSet which is replacement of
+ * current node otherwise
+ */
+ public JointSet processBackRefReplacement() {
+ return null;
+ }
+
+ /**
+ * This method is used for traversing nodes after the
+ * first stage of compilation.
+ */
+ public void processSecondPass() {
+ this.isSecondPassVisited = true;
+
+ if (next != null) {
+
+ if (!next.isSecondPassVisited) {
+
+ /*
+ * Add here code to do during the pass
+ */
+ JointSet set = next.processBackRefReplacement();
+
+ if (set != null) {
+ next.isSecondPassVisited = true;
+ next =(AbstractSet) set;
+ }
+
+ /*
+ * End code to do during the pass
+ */
+ next.processSecondPass();
+ } else {
+
+ /*
+ * We reach node through next but it is already traversed.
+ * You can see this situation for AltGroupQuantifierSet.next
+ * when we reach this node through
+ * AltGroupQuantifierSet.innerset. ... .next
+ */
+
+ /*
+ * Add here code to do during the pass
+ */
+ if (next instanceof SingleSet
+ && ((FSet) ((JointSet) next).fSet).isBackReferenced) {
+ next = next.next;
+ }
+
+ /*
+ * End code to do during the pass
+ */
+ }
+ }
+ }
}
Added: incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/BackReferencedSingleSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/BackReferencedSingleSet.java?rev=395158&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/BackReferencedSingleSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/BackReferencedSingleSet.java Wed Apr 19 00:50:10 2006
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Nikolay Kuznetsov
+ * @version $Revision: 1.1 $
+ */
+
+package java.util.regex;
+
+/**
+ * Group node over subexpression w/o alternations.
+ * This node is used if current group is referenced
+ * via backreference.
+ */
+
+class BackReferencedSingleSet extends SingleSet {
+
+ /*
+ * This class is needed only for overwriting find()
+ * and findBack() methods of SingleSet class, which is being
+ * back referenced. The following example explains the need
+ * for such substitution:
+ * Let's consider the pattern ".*(.)\\1".
+ * Leading .* works as follows: finds line terminator and runs findBack
+ * from that point. findBack method in its turn (in contrast to matches)
+ * sets group boundaries on the back trace. Thus at the point we
+ * try to match back reference(\\1) groups are not yet set.
+ *
+ * To fix this problem we replace backreferenced groups with instances of
+ * this class, which will use matches instead of find; this will affect
+ * perfomance, but ensure correctness of the match.
+ */
+
+ public BackReferencedSingleSet(AbstractSet child, FSet fSet) {
+ super(child, fSet);
+ }
+
+ public BackReferencedSingleSet(SingleSet node) {
+ super(node.kid, ((FSet) node.fSet));
+ }
+
+ public int find(int stringIndex, CharSequence testString,
+ MatchResultImpl matchResult) {
+ int res = 0;
+ int lastIndex = matchResult.getRightBound();
+ int startSearch = stringIndex;
+
+ for (; startSearch <= lastIndex; startSearch++) {
+ int saveStart = matchResult.getStart(groupIndex);
+
+ matchResult.setStart(groupIndex, startSearch);
+ res = kid.matches(startSearch, testString, matchResult);
+ if (res >= 0) {
+ res = startSearch;
+ break;
+ } else {
+ matchResult.setStart(groupIndex, saveStart);
+ }
+ }
+
+ return res;
+ }
+
+ public int findBack(int stringIndex, int lastIndex,
+ CharSequence testString, MatchResultImpl matchResult) {
+ int res = 0;
+ int startSearch = lastIndex;
+
+ for (; startSearch >= stringIndex; startSearch--) {
+ int saveStart = matchResult.getStart(groupIndex);
+
+ matchResult.setStart(groupIndex, startSearch);
+ res = kid.matches(startSearch, testString, matchResult);
+ if (res >= 0) {
+ res = startSearch;
+ break;
+ } else {
+ matchResult.setStart(groupIndex, saveStart);
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * This method is used for replacement backreferenced
+ * sets.
+ *
+ * @param prev - node who references to this node
+ */
+ public JointSet processBackRefReplacement() {
+ return null;
+ }
+}
Modified: incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/FSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/FSet.java?rev=395158&r1=395157&r2=395158&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/FSet.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/FSet.java Wed Apr 19 00:50:10 2006
@@ -1,84 +1,86 @@
-/*
- * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Nikolay A. Kuznetsov
- * @version $Revision: 1.8.2.2 $
- */
-package java.util.regex;
-
-/**
- * The node which marks end of the particular group.
- * @author Nikolay A. Kuznetsov
- * @version $Revision: 1.8.2.2 $
- */
-class FSet extends AbstractSet {
-
- static PossessiveFSet posFSet = new PossessiveFSet();
-
- private int groupIndex;
-
- public FSet(int groupIndex) {
- this.groupIndex = groupIndex;
- }
-
- public int matches(int stringIndex, CharSequence testString,
- MatchResultImpl matchResult) {
- int end = matchResult.getEnd(groupIndex);
- matchResult.setEnd(groupIndex, stringIndex);
- int shift = next.matches(stringIndex, testString, matchResult);
- /*
- * if(shift >=0 && matchResult.getEnd(groupIndex) == -1) {
- * matchResult.setEnd(groupIndex, stringIndex); }
- */
- if (shift < 0)
- matchResult.setEnd(groupIndex, end);
- return shift;
- }
-
- public int getGroupIndex() {
- return groupIndex;
- }
-
- protected String getName() {
- return "fSet";
- }
-
- public boolean hasConsumed(MatchResultImpl mr) {
- return false;
- }
-
- /**
- * Marks the end of the particular group and not take into account possible
- * kickbacks(required for atomic groups, for instance)
- *
- */
- static class PossessiveFSet extends AbstractSet {
-
- public int matches(int stringIndex, CharSequence testString,
- MatchResultImpl matchResult) {
- return stringIndex;
- }
-
- protected String getName() {
- return "posFSet";
- }
-
- public boolean hasConsumed(MatchResultImpl mr) {
- return false;
- }
- }
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.8.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * The node which marks end of the particular group.
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.8.2.2 $
+ */
+class FSet extends AbstractSet {
+
+ static PossessiveFSet posFSet = new PossessiveFSet();
+
+ boolean isBackReferenced = false;
+
+ private int groupIndex;
+
+ public FSet(int groupIndex) {
+ this.groupIndex = groupIndex;
+ }
+
+ public int matches(int stringIndex, CharSequence testString,
+ MatchResultImpl matchResult) {
+ int end = matchResult.getEnd(groupIndex);
+ matchResult.setEnd(groupIndex, stringIndex);
+ int shift = next.matches(stringIndex, testString, matchResult);
+ /*
+ * if(shift >=0 && matchResult.getEnd(groupIndex) == -1) {
+ * matchResult.setEnd(groupIndex, stringIndex); }
+ */
+ if (shift < 0)
+ matchResult.setEnd(groupIndex, end);
+ return shift;
+ }
+
+ public int getGroupIndex() {
+ return groupIndex;
+ }
+
+ protected String getName() {
+ return "fSet";
+ }
+
+ public boolean hasConsumed(MatchResultImpl mr) {
+ return false;
+ }
+
+ /**
+ * Marks the end of the particular group and not take into account possible
+ * kickbacks(required for atomic groups, for instance)
+ *
+ */
+ static class PossessiveFSet extends AbstractSet {
+
+ public int matches(int stringIndex, CharSequence testString,
+ MatchResultImpl matchResult) {
+ return stringIndex;
+ }
+
+ protected String getName() {
+ return "posFSet";
+ }
+
+ public boolean hasConsumed(MatchResultImpl mr) {
+ return false;
+ }
+ }
}
Modified: incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/JointSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/JointSet.java?rev=395158&r1=395157&r2=395158&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/JointSet.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex/src/main/java/java/util/regex/JointSet.java Wed Apr 19 00:50:10 2006
@@ -1,99 +1,151 @@
-/*
- * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Nikolay A. Kuznetsov
- * @version $Revision: 1.12.2.2 $
- */
-package java.util.regex;
-
-import java.util.ArrayList;
-
-/**
- * Represents group, which is alternation of other subexpression.
- * One should think about "group" in this model as JointSet opening
- * group and corresponding FSet closing group.
- *
- * @author Nikolay A. Kuznetsov
- * @version $Revision: 1.12.2.2 $
- */
-class JointSet extends AbstractSet {
-
- protected ArrayList children;
-
- protected AbstractSet fSet;
-
- protected int groupIndex;
-
- protected JointSet() {
- }
-
- public JointSet(ArrayList children, FSet fSet) {
- this.children = children;
- this.fSet = fSet;
- this.groupIndex = fSet.getGroupIndex();
- }
-
- /**
- * Returns stringIndex+shift, the next position to match
- */
- public int matches(int stringIndex, CharSequence testString,
- MatchResultImpl matchResult) {
- int start = matchResult.getStart(groupIndex);
- matchResult.setStart(groupIndex, stringIndex);
- int size = children.size();
- for (int i = 0; i < size; i++) {
- AbstractSet e = (AbstractSet) children.get(i);
- int shift = e.matches(stringIndex, testString, matchResult);
- if (shift >= 0) {
- return shift;
- }
- }
- matchResult.setStart(groupIndex, start);
- return -1;
- }
-
- public void setNext(AbstractSet next) {
- fSet.setNext(next);
- }
-
- public AbstractSet getNext() {
- return fSet.getNext();
- }
-
- protected String getName() {
- return "JointSet";
- }
-
- public int getGroup() {
- return groupIndex;
- }
-
- public boolean first(AbstractSet set) {
- for (java.util.Iterator i = children.iterator(); i.hasNext();) {
- if (((AbstractSet) i.next()).first(set)) {
- return true;
- }
- }
-
- return false;
- }
-
- public boolean hasConsumed(MatchResultImpl matchResult) {
- return !(matchResult.getEnd(groupIndex) >= 0 && matchResult
- .getStart(groupIndex) == matchResult.getEnd(groupIndex));
- }
-}
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+package java.util.regex;
+
+import java.util.ArrayList;
+
+/**
+ * Represents group, which is alternation of other subexpression.
+ * One should think about "group" in this model as JointSet opening
+ * group and corresponding FSet closing group.
+ *
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+class JointSet extends AbstractSet {
+
+ protected ArrayList children;
+
+ protected AbstractSet fSet;
+
+ protected int groupIndex;
+
+ protected JointSet() {
+ }
+
+ public JointSet(ArrayList children, FSet fSet) {
+ this.children = children;
+ this.fSet = fSet;
+ this.groupIndex = fSet.getGroupIndex();
+ }
+
+ /**
+ * Returns stringIndex+shift, the next position to match
+ */
+ public int matches(int stringIndex, CharSequence testString,
+ MatchResultImpl matchResult) {
+ int start = matchResult.getStart(groupIndex);
+ matchResult.setStart(groupIndex, stringIndex);
+ int size = children.size();
+ for (int i = 0; i < size; i++) {
+ AbstractSet e = (AbstractSet) children.get(i);
+ int shift = e.matches(stringIndex, testString, matchResult);
+ if (shift >= 0) {
+ return shift;
+ }
+ }
+ matchResult.setStart(groupIndex, start);
+ return -1;
+ }
+
+ public void setNext(AbstractSet next) {
+ fSet.setNext(next);
+ }
+
+ public AbstractSet getNext() {
+ return fSet.getNext();
+ }
+
+ protected String getName() {
+ return "JointSet";
+ }
+
+ public int getGroup() {
+ return groupIndex;
+ }
+
+ public boolean first(AbstractSet set) {
+ for (java.util.Iterator i = children.iterator(); i.hasNext();) {
+ if (((AbstractSet) i.next()).first(set)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public boolean hasConsumed(MatchResultImpl matchResult) {
+ return !(matchResult.getEnd(groupIndex) >= 0 && matchResult
+ .getStart(groupIndex) == matchResult.getEnd(groupIndex));
+ }
+
+ /**
+ * This method is used for traversing nodes after the
+ * first stage of compilation.
+ */
+ public void processSecondPass() {
+ this.isSecondPassVisited = true;
+
+ if (fSet != null && !fSet.isSecondPassVisited) {
+
+ /*
+ * Add here code to do during the pass
+ */
+
+ /*
+ * End code to do during the pass
+ */
+ fSet.processSecondPass();
+ }
+
+ if (children != null) {
+ int childrenSize = children.size();
+
+ for (int i = 0; i < childrenSize; i++) {
+ AbstractSet child = (AbstractSet) children.get(i);
+
+ /*
+ * Add here code to do during the pass
+ */
+
+ JointSet set = child.processBackRefReplacement();
+
+ if (set != null) {
+ child.isSecondPassVisited = true;
+ children.remove(i);
+ children.add(i, set);
+ child = (AbstractSet) set;
+ }
+
+ /*
+ * End code to do during the pass
+ */
+ if (!child.isSecondPassVisited) {
+ child.processSecondPass();
+ }
+ }
+ }
+
+ if (next != null) {
+ super.processSecondPass();
+ }
+ }
+}