Source code: com/memoire/re/RETokenOneOf.java
1
2
3 package com.memoire.re;
4 import com.memoire.re.*;
5
6 /*
7 * gnu/regexp/RETokenOneOf.java
8 * Copyright (C) 1998 Wes Biggs
9 *
10 * This library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library General Public License as published
12 * by the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library General Public License for more details.
19 *
20 * You should have received a copy of the GNU Library General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25
26 import java.util.Vector;
27
28 class RETokenOneOf extends REToken {
29 private Vector options;
30 private boolean negative;
31
32 // This constructor is used for convenience when we know the set beforehand,
33 // e.g. \d --> new RETokenOneOf("0123456789",false, ..)
34 // \D --> new RETokenOneOf("0123456789",true, ..)
35
36 RETokenOneOf(int f_subIndex, String f_options,boolean f_negative,boolean f_insens) {
37 super(f_subIndex);
38 options = new Vector();
39 negative = f_negative;
40 for (int i=0; i<f_options.length(); i++)
41 options.addElement(new RETokenChar(f_subIndex,f_options.charAt(i),f_insens));
42 }
43
44 RETokenOneOf(int f_subIndex, Vector f_options,boolean f_negative) {
45 super(f_subIndex);
46 options = f_options;
47 negative = f_negative;
48 }
49
50 int getMinimumLength() {
51 int min = Integer.MAX_VALUE;
52 int x;
53 for (int i=0; i < options.size(); i++) {
54 if ((x = ((REToken) options.elementAt(i)).getMinimumLength()) < min)
55 min = x;
56 }
57 return min;
58 }
59
60 int[] match(RECharIndexed input, int index, int eflags, REMatch mymatch) {
61 if (negative && (input.charAt(index) == RECharIndexed.OUT_OF_BOUNDS))
62 return null;
63
64 int[] newIndex;
65 int[] possibles = new int[0];
66 REToken tk;
67 for (int i=0; i < options.size(); i++) {
68 tk = (REToken) options.elementAt(i);
69 newIndex = tk.match(input,index,eflags,mymatch);
70
71 // Voodoo.
72 if ((newIndex == null) && (tk instanceof RE) && (tk.m_subIndex > 0)) {
73 mymatch.reset(tk.m_subIndex + 1);
74 }
75
76 if (newIndex != null) { // match was successful
77 if (negative) return null;
78 // Add newIndex to list of possibilities.
79
80 int[] temp = new int[possibles.length + newIndex.length];
81 System.arraycopy(possibles,0,temp,0,possibles.length);
82 for (int j = 0; j < newIndex.length; j++)
83 temp[possibles.length + j] = newIndex[j];
84 possibles = temp;
85 }
86 } // try next option
87 // Now possibles is array of all possible matches.
88 // Try next with each possibility.
89
90 int[] doables = new int[0];
91 for (int i = 0; i < possibles.length; i++) {
92 newIndex = next(input,possibles[i],eflags,mymatch);
93 if (newIndex != null) {
94 int[] temp = new int[doables.length + newIndex.length];
95 System.arraycopy(doables,0,temp,0,doables.length);
96 for (int j = 0; j < newIndex.length; j++)
97 temp[doables.length + j] = newIndex[j];
98 doables = temp;
99 } else {
100 // Voodoo.
101 if (m_subIndex > 0) {
102 mymatch.reset(m_subIndex + 1);
103 }
104 }
105
106 }
107
108 if (doables.length > 0)
109 return (negative) ?
110 null : doables;
111 else return (negative) ?
112 next(input,index+1,eflags,mymatch) : null;
113
114 // index+1 works for [^abc] lists, not for generic lookahead (--> index)
115 }
116
117 void dump(StringBuffer os) {
118 os.append(negative ? "[^" : "(?:");
119 for (int i = 0; i < options.size(); i++) {
120 if (!negative && (i > 0)) os.append('|');
121 ((REToken) options.elementAt(i)).dumpAll(os);
122 }
123 os.append(negative ? ']' : ')');
124 }
125
126 // Overrides REToken.chain
127 boolean chain(REToken f_next) {
128 super.chain(f_next);
129 for (int i = 0; i < options.size(); i++)
130 ((REToken) options.elementAt(i)).setUncle(f_next);
131 return true;
132 }
133
134 /*
135 void setUncle(REToken f_next) {
136 for (int i = 0; i < options.size(); i++)
137 ((REToken) options.elementAt(i)).setUncle(f_next);
138 }
139 */
140 }