2 // This software is now distributed according to
3 // the Lesser Gnu Public License. Please see
4 // http://www.gnu.org/copyleft/lesser.txt for
8 package com.stevesoft.pat;
13 Shareware: package pat
14 <a href="copyright.html">Copyright 2001, Steven R. Brandt</a>
17 * Class Pattern is the base class on which all the other pattern elements are
21 public abstract class Pattern
24 * The ESC character, the user can provide his own value for the escape
25 * character through regex.esc
27 public final static char ESC = '\\';
29 final static String PROTECT_THESE = "[]{}(),$,-\"^.";
32 * The interal match function, it must be provided by any class which wishes
35 public abstract int matchInternal(int i, Pthings p);
37 public abstract String toString();
39 // Class Pattern is a singly linked list
40 // chained together by member next. The member
41 // parent is used so that sub patterns can access
42 // the chain they are branching from.
43 Pattern next = null, parent = null;
46 * This gets the next element of a Pattern that we wish to match. If we are at
47 * the end of a subchain of patterns, it will return us to the parent chain.
49 public Pattern getNext()
51 return next != null ? next : (parent == null ? null : parent.getNext());
55 * Call this method if you have a pattern element that takes a sub pattern
56 * (such as Or), and after you have added a sub pattern to the current pattern
59 public void setParent(Pattern p)
72 * This determines if the remainder of a Pattern matches. Type "return
73 * nextMatch" from within matchInternal if the current Pattern matches.
74 * Otherwise, return a -1.
76 public int nextMatch(int i, Pthings pt)
78 Pattern p = getNext();
80 * if(p == null) return i; return p.matchInternal(i,pt);
82 return p == null ? i : p.matchInternal(i, pt);
86 * This is a toString() for the remainder of the Pattern elements after this
87 * one. use this when overriding toString(). Called from within toString().
89 public String nextString()
95 return next.toString();
98 /** a method to detect whether char c is in String s */
99 final static boolean inString(char c, String s)
102 for (i = 0; i < s.length(); i++)
104 if (s.charAt(i) == c)
113 * A method to create a string that protects the characters listed in
114 * PROTECT_THESE by prepending the esc character. The esc character itself is
115 * automatically protected.
117 final static String protect(String s, String PROTECT_THESE, char esc)
120 StringBuffer sb = new StringBuffer();
121 String p = PROTECT_THESE + esc;
122 for (i = 0; i < s.length(); i++)
124 char c = s.charAt(i);
131 return sb.toString();
135 * This can be used to perform a match test from within class Pattern.
137 public int match(StringLike s, Pthings pt)
139 return matchAt(s, 0, pt);
143 * This can be used to perform a match test from within class Pattern.
145 public int matchAt(StringLike s, int i, Pthings pt)
148 int r = matchInternal(i, pt);
153 mfrom = r < i ? r + 1 : i;
154 return r < i ? i - r - 1 : r - i;
159 // Detect masked characters
160 final boolean Masked(int i, Pthings pt)
162 return pt.cbits == null ? false : pt.cbits.get(i);
165 /** add a Pattern to the singly-linked Pattern chain. */
166 public Pattern add(Pattern p)
186 * The minimum number of characters which this pattern element can match.
188 public patInt minChars()
190 return new patInt(0);
194 * The maximum number of characters which this pattern element can match.
196 public patInt maxChars()
201 /** return minimum number of characters in pattern */
202 public final patInt countMinChars()
205 patInt sum = new patInt(0);
208 sum.pluseq(p.minChars());
214 /** return maximum number of characters in pattern */
215 public final patInt countMaxChars()
218 patInt sum = new patInt(0);
221 sum.pluseq(p.maxChars());
227 // This method is only needed by Multi_stage2 so far...
228 // the reason is that it may try something else after a
229 // match succeeds. OrMark will only record the last thing
230 // tried in marks, so we need to backup the result of the
231 // last successful match and restore it if the next one
233 final int testMatch(Pattern p, int pos, Pthings pt)
236 if (pt.marks != null)
240 tab = new int[pt.marks.length];
241 for (int i = 0; i < tab.length; i++)
243 tab[i] = pt.marks[i];
245 } catch (Throwable t)
249 int ret = p.matchInternal(pos, pt);
258 * Clones this pattern elements without cloning others in the linked list.
260 Pattern clone1(Hashtable h)
262 throw new Error("No such method as clone1 for " + getClass().getName());
265 Pattern clone(Hashtable h)
267 Pattern p = (Pattern) h.get(this);
275 throw new Error("Null from clone1!");
281 p.next = next.clone(h);
285 p.parent = parent.clone(h);
290 public boolean equals(Object o)