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;
10 import jalview.util.MessageManager;
12 import java.util.Hashtable;
15 Shareware: package pat
16 <a href="copyright.html">Copyright 2001, Steven R. Brandt</a>
19 * Class Pattern is the base class on which all the other pattern elements are
23 public abstract class Pattern
26 * The ESC character, the user can provide his own value for the escape
27 * character through regex.esc
29 public final static char ESC = '\\';
31 final static String PROTECT_THESE = "[]{}(),$,-\"^.";
34 * The interal match function, it must be provided by any class which wishes
37 public abstract int matchInternal(int i, Pthings p);
39 public abstract String toString();
41 // Class Pattern is a singly linked list
42 // chained together by member next. The member
43 // parent is used so that sub patterns can access
44 // the chain they are branching from.
45 Pattern next = null, parent = null;
48 * This gets the next element of a Pattern that we wish to match. If we are at
49 * the end of a subchain of patterns, it will return us to the parent chain.
51 public Pattern getNext()
53 return next != null ? next : (parent == null ? null : parent.getNext());
57 * Call this method if you have a pattern element that takes a sub pattern
58 * (such as Or), and after you have added a sub pattern to the current pattern
61 public void setParent(Pattern p)
74 * This determines if the remainder of a Pattern matches. Type "return
75 * nextMatch" from within matchInternal if the current Pattern matches.
76 * Otherwise, return a -1.
78 public int nextMatch(int i, Pthings pt)
80 Pattern p = getNext();
82 * if(p == null) return i; return p.matchInternal(i,pt);
84 return p == null ? i : p.matchInternal(i, pt);
88 * This is a toString() for the remainder of the Pattern elements after this
89 * one. use this when overriding toString(). Called from within toString().
91 public String nextString()
97 return next.toString();
100 /** a method to detect whether char c is in String s */
101 final static boolean inString(char c, String s)
104 for (i = 0; i < s.length(); i++)
106 if (s.charAt(i) == c)
115 * A method to create a string that protects the characters listed in
116 * PROTECT_THESE by prepending the esc character. The esc character itself is
117 * automatically protected.
119 final static String protect(String s, String PROTECT_THESE, char esc)
122 StringBuffer sb = new StringBuffer();
123 String p = PROTECT_THESE + esc;
124 for (i = 0; i < s.length(); i++)
126 char c = s.charAt(i);
133 return sb.toString();
137 * This can be used to perform a match test from within class Pattern.
139 public int match(StringLike s, Pthings pt)
141 return matchAt(s, 0, pt);
145 * This can be used to perform a match test from within class Pattern.
147 public int matchAt(StringLike s, int i, Pthings pt)
150 int r = matchInternal(i, pt);
155 mfrom = r < i ? r + 1 : i;
156 return r < i ? i - r - 1 : r - i;
161 // Detect masked characters
162 final boolean Masked(int i, Pthings pt)
164 return pt.cbits == null ? false : pt.cbits.get(i);
167 /** add a Pattern to the singly-linked Pattern chain. */
168 public Pattern add(Pattern p)
188 * The minimum number of characters which this pattern element can match.
190 public patInt minChars()
192 return new patInt(0);
196 * The maximum number of characters which this pattern element can match.
198 public patInt maxChars()
203 /** return minimum number of characters in pattern */
204 public final patInt countMinChars()
207 patInt sum = new patInt(0);
210 sum.pluseq(p.minChars());
216 /** return maximum number of characters in pattern */
217 public final patInt countMaxChars()
220 patInt sum = new patInt(0);
223 sum.pluseq(p.maxChars());
229 // This method is only needed by Multi_stage2 so far...
230 // the reason is that it may try something else after a
231 // match succeeds. OrMark will only record the last thing
232 // tried in marks, so we need to backup the result of the
233 // last successful match and restore it if the next one
235 final int testMatch(Pattern p, int pos, Pthings pt)
238 if (pt.marks != null)
242 tab = new int[pt.marks.length];
243 for (int i = 0; i < tab.length; i++)
245 tab[i] = pt.marks[i];
247 } catch (Throwable t)
251 int ret = p.matchInternal(pos, pt);
260 * Clones this pattern elements without cloning others in the linked list.
262 Pattern clone1(Hashtable h)
264 throw new Error(MessageManager.formatMessage(
265 "error.no_such_method_as_clone1_for", new String[] { getClass()
269 Pattern clone(Hashtable h)
271 Pattern p = (Pattern) h.get(this);
279 throw new Error(MessageManager.getString("error.null_from_clone1"));
285 p.next = next.clone(h);
289 p.parent = parent.clone(h);
294 public boolean equals(Object o)