1   /*
2    *  LeftHandSide.java - transducer class
3    *
4    *  Copyright (c) 1998-2005, 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: LeftHandSide.java,v 1.10 2005/01/11 13:51:36 ian Exp $
14   */
15  
16  
17  package gate.jape;
18  
19  import java.io.Serializable;
20  import java.util.*;
21  
22  import gate.AnnotationSet;
23  import gate.Document;
24  import gate.util.Strings;
25  
26  
27  /**
28    * The LHS of a CPSL rule. The pattern part. Has a ConstraintGroup and
29    * binding information that associates labels with ComplexPatternElements.
30    * Provides the Matcher interface.
31    */
32  public class LeftHandSide implements Matcher, JapeConstants, Serializable
33  {
34  
35    /** Debug flag */
36    private static final boolean DEBUG = false;
37  
38    /** The constraint group making up this LHS. */
39    private ConstraintGroup constraintGroup;
40  
41    /** Mapping of binding names to ComplexPatternElements */
42    private HashMap bindingTable;
43  
44    /** Flag for whether our last match was successful or not. */
45    private boolean hasMatched = false;
46  
47    /** Construction from a ConstraintGroup */
48    public LeftHandSide(ConstraintGroup constraintGroup) {
49      this.constraintGroup = constraintGroup;
50      bindingTable = new HashMap();
51      hasMatched = false;
52    } // construction from ConstraintGroup
53  
54    /** Add a binding record. */
55    public void addBinding(
56      String bindingName,
57      ComplexPatternElement binding,
58      HashSet bindingNameSet,
59      boolean macroRef
60    ) throws JapeException {
61      if(bindingTable.get(bindingName) != null)
62        throw new JapeException(
63          "LeftHandSide.addBinding: " + bindingName + " already bound"
64        );
65      bindingTable.put(bindingName, binding);
66      bindingNameSet.add(bindingName);
67  
68      // if it was a macro ref, we need to recursively set up bindings
69      // in any CPEs that this one contains
70      if(macroRef) {
71        for(Iterator i = binding.getCPEs(); i.hasNext(); ) {
72          binding = (ComplexPatternElement) i.next();
73          bindingName = binding.getBindingName();
74          if(bindingName == null) // not all CPEs have binding names
75            continue;
76          if(bindingTable.get(bindingName) != null)
77            throw new JapeException(
78              "LeftHandSide.addBinding: " + bindingName + " already bound"
79            );
80          bindingTable.put(bindingName, binding);
81          bindingNameSet.add(bindingName);
82        } // for each binding
83      } // macroRef
84  
85    } // addBinding
86  
87    /** Finish: replace dynamic data structures with Java arrays; called
88      * after parsing.
89      */
90    public void finish() {
91      constraintGroup.finish();
92    } // finish
93  
94    /** Get annotations via a binding name. */
95    public AnnotationSet getBoundAnnots(String bindingName) {
96      ComplexPatternElement pat =
97        (ComplexPatternElement) bindingTable.get(bindingName);
98      if(pat == null) return null;
99      return pat.getMatchedAnnots();
100   } // getBoundAnnots
101 
102   /** For debugging only.
103     * Return a set of all annotations matched by the LHS during the
104     * last call to matches. (May be null.)
105     */
106   AnnotationSet getMatchedAnnots() {
107     return constraintGroup.getMatchedAnnots();
108   } // getMatchedAnnots
109 
110   /** Clear the matched annotations cached in pattern elements. */
111   public void reset() {
112     constraintGroup.reset();
113     hasMatched = false;
114   } // reset
115 
116   /** Was the last match successful? */
117   public boolean hasMatched() { return hasMatched; }
118 
119   /** Does the LHS match the document at this position? */
120   public boolean matches(
121     Document doc, int position, MutableInteger newPosition
122   ) {
123      boolean status = constraintGroup.matches(doc, position, newPosition);
124      //Debug.pr(this, "LHS: status(" + status + "); this: " + this.toString());
125 
126      if(! status) { // purge caches of matched annotations
127        constraintGroup.reset();
128        hasMatched = false;
129      } else {
130        hasMatched = true;
131      }
132      return status;
133   }  // matches
134 
135   /** Create a string representation of the object. */
136   public String toString() { return toString(""); }
137 
138   /** Create a string representation of the object. */
139   public String toString(String pad) {
140     String newline = Strings.getNl();
141     String newPad = Strings.addPadding(pad, INDENT_PADDING);
142 
143     StringBuffer buf = new StringBuffer(pad +
144       "LHS: hasMatched(" + hasMatched + "); constraintGroup(" + newline +
145       constraintGroup.toString(newPad) + newline + pad +
146       "); bindingTable(" + newline + pad
147     );
148 
149     for(Iterator i = bindingTable.keySet().iterator(); i.hasNext(); ) {
150       String bName = ((String) i.next());
151       ComplexPatternElement cpe = ((ComplexPatternElement)
152                                         bindingTable.get(bName));
153       buf.append(
154         pad + "bT.bn(" + bName + "), cpe.bn(" + cpe.getBindingName() + ")"
155       );
156     }
157 
158     buf.append(newline + pad + ") LHS." + newline);
159 
160     return buf.toString();
161   } // toString
162 
163   /** Get the constraint group */
164   public ConstraintGroup getConstraintGroup(){
165     return constraintGroup;
166   }
167 
168 } // class LeftHandSide
169 
170 
171 // $Log: LeftHandSide.java,v $
172 // Revision 1.10  2005/01/11 13:51:36  ian
173 // Updating copyrights to 1998-2005 in preparation for v3.0
174 //
175 // Revision 1.9  2004/07/21 17:10:08  akshay
176 // Changed copyright from 1998-2001 to 1998-2004
177 //
178 // Revision 1.8  2004/03/25 13:01:13  valyt
179 // Imports optimisation throughout the Java sources
180 // (to get rid of annoying warnings in Eclipse)
181 //
182 // Revision 1.7  2001/09/12 11:59:33  kalina
183 // Changed the old JAPE stuff to use the new Collections API,
184 // instead of com.objectspace stuff. Will eliminate that library
185 // completely very soon! Just one class left to re-implement,
186 //
187 // ParseCPSL.jj changed accordingly. All tested and no smoke.
188 //
189 // Revision 1.6  2000/11/08 16:35:03  hamish
190 // formatting
191 //
192 // Revision 1.5  2000/10/16 16:44:33  oana
193 // Changed the comment of DEBUG variable
194 //
195 // Revision 1.4  2000/10/10 15:36:36  oana
196 // Changed System.out in Out and System.err in Err;
197 // Added the DEBUG variable seted on false;
198 // Added in the header the licence;
199 //
200 // Revision 1.3  2000/05/02 16:54:26  hamish
201 // comment
202 //
203 // Revision 1.2  2000/04/14 18:02:46  valyt
204 // Added some gate.fsm classes
205 // added some accessor function in old jape classes
206 //
207 // Revision 1.1  2000/02/23 13:46:08  hamish
208 // added
209 //
210 // Revision 1.1.1.1  1999/02/03 16:23:01  hamish
211 // added gate2
212 //
213 // Revision 1.14  1998/11/01 21:21:37  hamish
214 // use Java arrays in transduction where possible
215 //
216 // Revision 1.13  1998/10/30 15:31:07  kalina
217 // Made small changes to make compile under 1.2 and 1.1.x
218 //
219 // Revision 1.12  1998/10/01 16:06:32  hamish
220 // new appelt transduction style, replacing buggy version
221 //
222 // Revision 1.11  1998/09/21 16:19:49  hamish
223 // cope with CPEs with no binding
224 //
225 // Revision 1.10  1998/09/17 16:48:32  hamish
226 // added macro defs and macro refs on LHS
227 //
228 // Revision 1.9  1998/08/19 20:21:39  hamish
229 // new RHS assignment expression stuff added
230 //
231 // Revision 1.8  1998/08/18 12:43:07  hamish
232 // fixed SPT bug, not advancing newPosition
233 //
234 // Revision 1.7  1998/08/12 19:05:45  hamish
235 // fixed multi-part CG bug; set reset to real reset and fixed multi-doc bug
236 //
237 // Revision 1.6  1998/08/12 15:39:37  hamish
238 // added padding toString methods
239 //
240 // Revision 1.5  1998/08/03 19:51:22  hamish
241 // rollback added
242 //
243 // Revision 1.4  1998/07/31 13:12:20  mks
244 // done RHS stuff, not tested
245 //
246 // Revision 1.3  1998/07/30 11:05:19  mks
247 // more jape
248 //
249 // Revision 1.2  1998/07/29 11:06:59  hamish
250 // first compiling version
251 //
252 // Revision 1.1.1.1  1998/07/28 16:37:46  hamish
253 // gate2 lives
254