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();
+    	}
+    }
+}