| ComplexPatternElement.java |
1 /*
2 * ComplexPatternElement.java - transducer class
3 *
4 * Copyright (c) 1998-2004, The University of Sheffield.
5 *
6 * This file is part of GATE (see http://gate.ac.uk/), and is free
7 * software, licenced under the GNU Library General Public License,
8 * Version 2, June 1991 (in the distribution as file licence.html,
9 * and also available at http://gate.ac.uk/gate/licence.html).
10 *
11 * Hamish Cunningham, 24/07/98
12 *
13 * $Id: ComplexPatternElement.java,v 1.10 2004/07/21 17:10:07 akshay Exp $
14 */
15
16
17 package gate.jape;
18
19 import java.util.Iterator;
20
21 import gate.AnnotationSet;
22 import gate.Document;
23 import gate.util.Strings;
24
25
26 /**
27 * A pattern element enclosed in round brackets. Has a
28 * ConstraintGroups, Kleene operator and binding name.
29 */
30 public class ComplexPatternElement extends PatternElement
31 implements JapeConstants, java.io.Serializable
32 {
33 /** Debug flag */
34 private static final boolean DEBUG = false;
35
36 /** Kleene operator (defaults to none). Other values: KLEENE_STAR (*);
37 * KLEENE_PLUS (+); KLEENE_QUERY (?) */
38 private int kleeneOp = NO_KLEENE_OP;
39
40 /** Binding name (may be null). */
41 private String bindingName = null;
42
43 /** Get binding name. */
44 public String getBindingName() { return bindingName; }
45
46 /** Get a list of CPEs that we contain. */
47 protected Iterator getCPEs() {
48 return constraintGroup.getCPEs();
49 } // getCPEs
50
51 /** The recursive definition of what pattern elements make up this one. */
52 private ConstraintGroup constraintGroup;
53
54 /** Construction from ConstraintGroup, Kleene operator type and binding
55 * name. Kleene types are defined in JapeConstants.
56 */
57 public ComplexPatternElement(
58 ConstraintGroup constraintGroup,
59 int kleeneOp,
60 String bindingName
61 ) {
62 this.constraintGroup = constraintGroup;
63 this.kleeneOp = kleeneOp;
64 this.bindingName = bindingName;
65 }
66
67 /** Need cloning for processing of macro references. See comments on
68 * <CODE>PatternElement.clone()</CODE>
69 */
70 public Object clone() {
71 ComplexPatternElement newPE = (ComplexPatternElement) super.clone();
72 newPE.constraintGroup = (ConstraintGroup) constraintGroup.clone();
73 return newPE;
74 } // clone
75
76 /** Finish: replace dynamic data structures with Java arrays; called
77 * after parsing.
78 */
79 public void finish() {
80 constraintGroup.finish();
81 } // finish
82
83 /** Access to the annotations that have been matched. */
84 public AnnotationSet getMatchedAnnots() {
85 return constraintGroup.getMatchedAnnots();
86 }
87
88 /** Reset: clear caches of annotations matched. */
89 public void reset() {
90 constraintGroup.reset();
91 super.reset();
92 } // reset
93
94 /** Multilevel rollback of annotation caches. */
95 public void rollback(int arity) {
96 /*Debug.pr(
97 this, "CPE rollback(" + arity + "), mH.size = " +
98 matchHistory.size() + Debug.getNl()
99 );*/
100
101 // for arity times, pop the arity history stack and
102 // ask the CG to rollback how ever many times it succeeded then
103 for(int i=0; i<arity; i++) {
104 int matchArity = ((Integer) matchHistory.pop()).intValue();
105 constraintGroup.rollback(matchArity);
106 }
107 } // rollback
108
109 /** Does this element match the document at this position? */
110 public boolean matches(
111 Document doc, int position, MutableInteger newPosition
112 ) {
113 /*Debug.pr(
114 this, "CPE.matches: trying at position " + position + Debug.getNl()
115 );*/
116 int matchArity = 0; // number of successful applications in this match
117 boolean firstTry = constraintGroup.matches(doc, position, newPosition);
118 if(firstTry) {
119 matchArity++;
120 /*Debug.pr(this,
121 "CPE.matches: first try succeeded, newPosition = " + newPosition.value
122 + Debug.getNl()
123 );*/
124 }
125 int theEndOfTheDocument = doc.getContent().size().intValue();
126
127 if(kleeneOp == NO_KLEENE_OP) {
128 if(firstTry) matchHistory.push(new Integer(matchArity));
129 return firstTry;
130 }
131 else if(kleeneOp == KLEENE_QUERY) {
132 if(firstTry) matchHistory.push(new Integer(matchArity));
133 /* Debug.pr(this, "CPE.matches: true, QUERY rule"); */
134 return true;
135 }
136 else if(kleeneOp == KLEENE_PLUS) {
137 if(! firstTry)
138 return false; // no cache purge: maybe we're under another * etc.
139 }
140 else if(kleeneOp == KLEENE_STAR && !firstTry) {
141 /*Debug.pr(this,
142 "CPE.matches: true, STAR rule, newPos("+newPosition.value+")");*/
143 matchHistory.push(new Integer(matchArity));
144 return true;
145 }
146
147 // we get here if we have either Kleene *, or Kleene +, and a
148 // successful first move. now we try it again as many times as it
149 // succeeds, store the final match arity and then return true
150 while(constraintGroup.matches(doc, newPosition.value, newPosition)) {
151 /*Debug.pr(this,
152 "CPE.matches: trying while loop, matchArity = " + matchArity);*/
153 matchArity++;
154
155 // if we've negated failing constraints, we may match for ever
156 if(newPosition.value >= theEndOfTheDocument) // stop at the end!
157 break;
158 } // while
159 matchHistory.push(new Integer(matchArity));
160 //Debug.pr(this,
161 // "CPE.matches: true, matchArity(" + matchArity + ") pushed");
162 return true;
163 } // matches
164
165
166 /** Create a string representation of the object. */
167 public String toString() { return toString(""); }
168
169 /** Create a string representation of the object. */
170 public String toString(String pad) {
171 String newline = Strings.getNl();
172
173 StringBuffer buf = new StringBuffer(
174 pad + "CPE: bindingName(" + bindingName + "); kleeneOp("
175 );
176
177 switch(kleeneOp) {
178 case NO_KLEENE_OP: buf.append("NO_KLEENE_OP"); break;
179 case KLEENE_STAR: buf.append("KLEENE_STAR"); break;
180 case KLEENE_QUERY: buf.append("KLEENE_QUERY"); break;
181 case KLEENE_PLUS: buf.append("KLEENE_PLUS"); break;
182 default: break;
183 }
184
185 buf.append(
186 "); constraintGroup(" + newline +
187 constraintGroup.toString(Strings.addPadding(pad, INDENT_PADDING)) +
188 newline + pad + ") CPE." + newline
189 );
190
191 return buf.toString();
192 } // toString
193 //needed by FSM
194
195 public int getKleeneOp(){ return kleeneOp; };
196
197 public ConstraintGroup getConstraintGroup(){ return constraintGroup; };
198
199 } // class ComplexPatternElement
200
201
202 // $Log: ComplexPatternElement.java,v $
203 // Revision 1.10 2004/07/21 17:10:07 akshay
204 // Changed copyright from 1998-2001 to 1998-2004
205 //
206 // Revision 1.9 2004/03/25 13:01:15 valyt
207 // Imports optimisation throughout the Java sources
208 // (to get rid of annoying warnings in Eclipse)
209 //
210 // Revision 1.8 2001/09/13 12:09:49 kalina
211 // Removed completely the use of jgl.objectspace.Array and such.
212 // Instead all sources now use the new Collections, typically ArrayList.
213 // I ran the tests and I ran some documents and compared with keys.
214 // JAPE seems to work well (that's where it all was). If there are problems
215 // maybe look at those new structures first.
216 //
217 // Revision 1.7 2001/09/12 11:59:33 kalina
218 // Changed the old JAPE stuff to use the new Collections API,
219 // instead of com.objectspace stuff. Will eliminate that library
220 // completely very soon! Just one class left to re-implement,
221 //
222 // ParseCPSL.jj changed accordingly. All tested and no smoke.
223 //
224 // Revision 1.6 2000/11/08 16:35:02 hamish
225 // formatting
226 //
227 // Revision 1.5 2000/10/26 10:45:30 oana
228 // Modified in the code style
229 //
230 // Revision 1.4 2000/10/16 16:44:33 oana
231 // Changed the comment of DEBUG variable
232 //
233 // Revision 1.3 2000/10/10 15:36:35 oana
234 // Changed System.out in Out and System.err in Err;
235 // Added the DEBUG variable seted on false;
236 // Added in the header the licence;
237 //
238 // Revision 1.2 2000/04/14 18:02:46 valyt
239 // Added some gate.fsm classes
240 // added some accessor function in old jape classes
241 //
242 // Revision 1.1 2000/02/23 13:46:05 hamish
243 // added
244 //
245 // Revision 1.1.1.1 1999/02/03 16:23:01 hamish
246 // added gate2
247 //
248 // Revision 1.14 1998/11/13 13:17:16 hamish
249 // merged in the doc length bug fix
250 //
251 // Revision 1.13 1998/11/12 17:47:27 kalina
252 // A bug fixed, wasn't restoring the document length
253 //
254 // Revision 1.12 1998/11/05 13:36:29 kalina
255 // moved to use array of JdmAttributes for selectNextAnnotation instead
256 // of a sequence
257 //
258 // Revision 1.11 1998/11/01 21:21:35 hamish
259 // use Java arrays in transduction where possible
260 //
261 // Revision 1.10 1998/10/06 16:16:09 hamish
262 // negation percolation during constrain add; position advance when none at end
263 //
264 // Revision 1.9 1998/10/01 16:06:29 hamish
265 // new appelt transduction style, replacing buggy version
266 //
267 // Revision 1.8 1998/09/26 09:19:14 hamish
268 // added cloning of PE macros
269 //
270 // Revision 1.7 1998/09/17 16:48:29 hamish
271 // added macro defs and macro refs on LHS
272 //
273 // Revision 1.6 1998/08/12 15:39:32 hamish
274 // added padding toString methods
275 //
276 // Revision 1.5 1998/08/05 21:58:04 hamish
277 // backend works on simple test
278 //
279 // Revision 1.4 1998/08/03 19:51:19 hamish
280 // rollback added
281 //
282 // Revision 1.3 1998/07/30 11:05:14 hamish
283 // more jape
284 //
285 // Revision 1.2 1998/07/29 11:06:54 hamish
286 // first compiling version
287 //
288 // Revision 1.1.1.1 1998/07/28 16:37:46 hamish
289 // gate2 lives
290