2003/06/28 06:54:18
[org.ibex.core.git] / src / gnu / regexp / RETokenOneOf.java
1 /*
2  *  gnu/regexp/RETokenOneOf.java
3  *  Copyright (C) 1998-2001 Wes Biggs
4  *
5  *  This library is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU Lesser General Public License as published
7  *  by the Free Software Foundation; either version 2.1 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 package gnu.regexp;
21 import java.util.Vector;
22
23 final class RETokenOneOf extends REToken {
24   private Vector options;
25   private boolean negative;
26
27   // This constructor is used for convenience when we know the set beforehand,
28   // e.g. \d --> new RETokenOneOf("0123456789",false, ..)
29   //      \D --> new RETokenOneOf("0123456789",true, ..)
30
31   RETokenOneOf(int subIndex, String optionsStr, boolean negative, boolean insens) {
32     super(subIndex);
33     options = new Vector();
34     this.negative = negative;
35     for (int i = 0; i < optionsStr.length(); i++)
36       options.addElement(new RETokenChar(subIndex,optionsStr.charAt(i),insens));
37   }
38
39   RETokenOneOf(int subIndex, Vector options, boolean negative) {
40     super(subIndex);
41     this.options = options;
42     this.negative = negative;
43   }
44
45   int getMinimumLength() {
46     int min = Integer.MAX_VALUE;
47     int x;
48     for (int i=0; i < options.size(); i++) {
49       if ((x = ((REToken) options.elementAt(i)).getMinimumLength()) < min)
50         min = x;
51     }
52     return min;
53   }
54
55     boolean match(CharIndexed input, REMatch mymatch) {
56     if (negative && (input.charAt(mymatch.index) == CharIndexed.OUT_OF_BOUNDS)) 
57       return false;
58
59     REMatch newMatch = null;
60     REMatch last = null;
61     REToken tk;
62     boolean isMatch;
63     for (int i=0; i < options.size(); i++) {
64         tk = (REToken) options.elementAt(i);
65         REMatch tryMatch = (REMatch) mymatch.clone();
66         if (tk.match(input, tryMatch)) { // match was successful
67             if (negative) return false;
68
69             if (next(input, tryMatch)) {
70                 // Add tryMatch to list of possibilities.
71                 if (last == null) {
72                     newMatch = tryMatch;
73                     last = tryMatch;
74                 } else {
75                     last.next = tryMatch;
76                     last = tryMatch;
77                 }
78             } // next succeeds
79         } // is a match
80     } // try next option
81
82     if (newMatch != null) {
83         if (negative) {
84             return false;
85         } else {
86             // set contents of mymatch equal to newMatch
87
88             // try each one that matched
89             mymatch.assignFrom(newMatch);
90             return true;
91         }
92     } else {
93         if (negative) {
94             ++mymatch.index;
95             return next(input, mymatch);
96         } else {
97             return false;
98         }
99     }
100
101     // index+1 works for [^abc] lists, not for generic lookahead (--> index)
102   }
103
104   void dump(StringBuffer os) {
105     os.append(negative ? "[^" : "(?:");
106     for (int i = 0; i < options.size(); i++) {
107       if (!negative && (i > 0)) os.append('|');
108       ((REToken) options.elementAt(i)).dumpAll(os);
109     }
110     os.append(negative ? ']' : ')');
111   }  
112 }