001 /*
002 * Copyright (c) 1995-2010, The University of Sheffield. See the file
003 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004 *
005 * This file is part of GATE (see http://gate.ac.uk/), and is free
006 * software, licenced under the GNU Library General Public License,
007 * Version 2, June 1991 (in the distribution as file licence.html,
008 * and also available at http://gate.ac.uk/gate/licence.html).
009 *
010 * Eric Sword, 09/19/08
011 *
012 * $Id$
013 */
014 package gate.jape;
015
016 import org.apache.log4j.Logger;
017 import gate.jape.JapeConstants;
018
019 import java.io.Serializable;
020
021 /**
022 * Representation of Kleene operators on expressions. Kleene operators
023 * indicate the number of repetitions over an expression that are legal.
024 * The most common are star (0 or more), plus (1 or more), and optional
025 * (0 or 1, also referred to as "kleene query"). The class can also
026 * represent a range with a fixed minimum, maximum, or both. Finally, a
027 * default type of single (exactly 1) is also defined.
028 *
029 * @version $Revision$
030 * @author esword
031 */
032 public class KleeneOperator implements Serializable {
033 protected static final Logger log = Logger.getLogger(KleeneOperator.class);
034
035 /**
036 * Enum containing the defined types of operators.
037 *
038 * @version $Revision$
039 * @author esword
040 */
041 public enum Type
042 {
043 SINGLE(""),
044 OPTIONAL("?"),
045 STAR("*"),
046 PLUS("+"),
047 RANGE("[x,y]");
048
049 private String symbol;
050
051 Type( )
052 {
053 }
054
055 Type( String symbol )
056 {
057 this.symbol = symbol;
058 }
059
060 public String getSymbol()
061 {
062 return( symbol );
063 }
064
065 /**
066 * Conversion routine from the old JapeConstants values to
067 * the type class.
068 * @param op
069 * @return
070 */
071 public static KleeneOperator.Type getFromJapeConstant(int op) {
072 switch(op) {
073 case JapeConstants.NO_KLEENE_OP:
074 return KleeneOperator.Type.SINGLE;
075 case JapeConstants.KLEENE_PLUS:
076 return KleeneOperator.Type.PLUS;
077 case JapeConstants.KLEENE_STAR:
078 return KleeneOperator.Type.PLUS;
079 case JapeConstants.KLEENE_QUERY:
080 return KleeneOperator.Type.OPTIONAL;
081 default:
082 throw new IllegalArgumentException("Unknown op code: " + op);
083 }
084 }
085
086 /**
087 * Conversion routine from the string symbol for a type to the type
088 * Enum.
089 *
090 * @param symbol
091 * @return
092 */
093 public static KleeneOperator.Type getFromSymbol(String symbol) {
094 for(Type t : Type.values()) {
095 if (t.getSymbol().equals(symbol))
096 return t;
097 }
098
099 return null;
100 }
101 }
102
103 private Type type;
104 private Integer min;
105 private Integer max;
106 private String displayString;
107
108 /**
109 * Create an operator with the given type, setting the
110 * appropriate min for each (and max when defined). This constructor
111 * should not be used for {@link Type#RANGE} operators. Use one of
112 * the other range-defining constructors in that case.
113 * @param type
114 */
115 public KleeneOperator(Type type) {
116 this.type = type;
117
118 //setup min and max in case needed
119 if (type == Type.SINGLE) {
120 min = 1;
121 max = 1;
122 }
123 else if (type == Type.OPTIONAL) {
124 min = 0;
125 max = 1;
126 }
127 else if (type == Type.STAR) {
128 min = 0;
129 //no set max
130 }
131 else if (type == Type.PLUS) {
132 min = 1;
133 //no set max
134 }
135 else if (type == Type.RANGE) {
136 //default to 1 and 1. Really, the other constructor should be used.
137 min = 1;
138 max = 1;
139 }
140 }
141
142 /**
143 * Create an operator with type RANGE and min and max both set to val.
144 * @param val
145 */
146 public KleeneOperator(Integer val) {
147 this(val, val);
148 }
149
150 /**
151 * Create an operator with type RANGE and the given min and max.
152 * @param min
153 * @param max
154 */
155 public KleeneOperator(Integer min, Integer max) {
156 this.type = Type.RANGE;
157
158 if (min != null && max != null && min > max)
159 throw new IllegalArgumentException("min cannot be greater than max: " + min + ", " + max);
160
161 this.min = min;
162 this.max = max;
163 }
164
165 /**
166 * The string representation for most operators is the operator symbol itself. For ranges, the
167 * min and max are shown. If min == max, only one is shown.
168 */
169 @Override
170 public String toString() {
171 if (type != Type.RANGE) return type.getSymbol();
172
173 if(displayString != null) return displayString;
174
175 StringBuilder sb = new StringBuilder("[");
176 sb.append(getMin());
177 if(!min.equals(max)) {
178 sb.append(",");
179 if(max != null) sb.append(max);
180 }
181 sb.append("]");
182
183 displayString = sb.toString();
184
185 return displayString;
186 }
187
188 /*
189 * =================================================================================================
190 * Getters and Setters
191 * =================================================================================================
192 */
193 public Type getType() {
194 return type;
195 }
196
197 public void setType(Type type) {
198 this.type = type;
199 }
200
201 public Integer getMin() {
202 return min;
203 }
204
205 public Integer getMax() {
206 return max;
207 }
208 }
|