001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2013, Michael Meyling <mime@qedeq.org>.
004 *
005 * "Hilbert II" is free software; you can redistribute
006 * it and/or modify it under the terms of the GNU General Public
007 * License as published by the Free Software Foundation; either
008 * version 2 of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 */
015
016 package org.qedeq.kernel.bo.parser;
017
018
019 /**
020 * This class describes an term or logical operator. An operator is of either
021 * prefix, infix or postfix type and has a minimum and maximum number of operands.
022 * It has a symbol or token that enables to recognize it and a QEDEQ representation.
023 * Each instance of this class is unique so two instances with the same parameters are
024 * different from each other.
025 *
026 * @author Michael Meyling
027 */
028 public final class Operator {
029
030 /** Marks infix operator. */
031 public static final int INFIX = 0;
032
033 /** Marks prefix operator. */
034 public static final int SIMPLE_PREFIX = 1;
035
036 /** Marks postfix operator. */
037 public static final int POSTFIX = 2;
038
039 /** Marks function operator. */
040 public static final int FUNCTION = 4;
041
042 /** Prefix, function, infix or postfix. See {@link #SIMPLE_PREFIX}, {@link #FUNCTION},
043 * {@link #INFIX} and {@link #POSTFIX}. */
044 private final int type;
045
046 /** Start symbol or token for this operator. */
047 private final String startSymbol;
048
049 /** Separator symbol or token for this operator. This could be a comma for example. */
050 private final String separatorSymbol;
051
052 /** End symbol or token for this operator. */
053 private final String endSymbol;
054
055 /** Operator priority. Highest is 0. */
056 private final int priority;
057
058 /** QEDEQ token for this operator. */
059 private final String qedeq;
060
061 /** First QEDEQ argument. Can be <code>null</code>. */
062 private final String qedeqArgument;
063
064 /** Minimum number of arguments. */
065 private final int min;
066
067 /** Maximum number of arguments. */
068 private final int max;
069
070
071 /**
072 * Constructor.
073 *
074 * @param symbol Symbol or token for this operator.
075 * @param qedeq QEDEQ operator symbol.
076 * @param qedeqArgument First Argument in QEDEQ-Syntax - if any.
077 * @param priority Operator priority, highest is 0.
078 * @param type Prefix, infix or postfix. See {@link #SIMPLE_PREFIX}, {@link #FUNCTION},
079 * {@link #INFIX} and {@link #POSTFIX}.
080 * @param min Minimum number of arguments for this operator.
081 */
082 public Operator(final String symbol,
083 final String qedeq,
084 final String qedeqArgument,
085 final int priority,
086 final int type,
087 final int min) {
088 this(symbol, qedeq, qedeqArgument, priority, type, min, -1);
089 }
090
091 /**
092 * Constructor.
093 *
094 * @param symbol Symbol or token for this operator.
095 * @param qedeq QEDEQ operator symbol.
096 * @param qedeqArgument First Argument in QEDEQ-Syntax - if any.
097 * @param priority Operator priority, highest is 0.
098 * @param type Prefix, infix or postfix. See {@link #SIMPLE_PREFIX},
099 * {@link #FUNCTION},
100 * {@link #INFIX} and {@link #POSTFIX}.
101 * @param min Minimum number of arguments for this operator.
102 * @param max Maximum number of arguments for this operator.
103 */
104 public Operator(final String symbol,
105 final String qedeq,
106 final String qedeqArgument,
107 final int priority,
108 final int type,
109 final int min,
110 final int max) {
111 this(symbol, null, null, qedeq, qedeqArgument, priority, type, min, max);
112 }
113
114 /**
115 * Constructor for prefix operators like <code>{x | x > 0}</code>.
116 *
117 * @param startSymbol Starting symbol or token for this operator.
118 * @param separatorSymbol Symbol or token that separates arguments for this operator.
119 * @param endSymbol End symbol or token for this operator.
120 * @param qedeq QEDEQ operator symbol.
121 * @param qedeqArgument First Argument in QEDEQ-Syntax - if any
122 * @param priority Operator priority, highest is 0.
123 * @param min Minimum number of arguments for this operator.
124 */
125 public Operator(final String startSymbol,
126 final String separatorSymbol,
127 final String endSymbol,
128 final String qedeq,
129 final String qedeqArgument,
130 final int priority,
131 final int min) {
132 this(startSymbol, separatorSymbol, endSymbol, qedeq, qedeqArgument, priority, SIMPLE_PREFIX,
133 min, -1);
134 }
135
136 /**
137 * Constructor for prefix operators like <code>{x, y, z}</code>.
138 *
139 * @param startSymbol Starting symbol or token for this operator.
140 * @param separatorSymbol Symbol or token that separates arguments for this operator.
141 * @param endSymbol End symbol or token for this operator.
142 * @param qedeq QEDEQ operator symbol.
143 * @param qedeqArgument First Argument in QEDEQ-Syntax - if any.
144 * @param priority Operator priority, highest is 0.
145 * @param min Minimum number of arguments for this operator.
146 * @param max Maximum number of arguments for this operator.
147 */
148 public Operator(final String startSymbol,
149 final String separatorSymbol,
150 final String endSymbol,
151 final String qedeq,
152 final String qedeqArgument,
153 final int priority,
154 final int min,
155 final int max) {
156 this(startSymbol, separatorSymbol, endSymbol, qedeq, qedeqArgument, priority, SIMPLE_PREFIX,
157 min, max);
158 }
159
160 /**
161 * Constructor.
162 *
163 * @param startSymbol Starting symbol or token for this operator.
164 * @param separatorSymbol Symbol or token that separates arguments for this operator.
165 * @param endSymbol End symbol or token for this operator.
166 * @param qedeq QEDEQ operator symbol.
167 * @param qedeqArgument First Argument in QEDEQ-Syntax - if any.
168 * @param priority Operator priority, highest is 0.
169 * @param type Prefix, infix or postfix. See {@link #SIMPLE_PREFIX},
170 * {@link #FUNCTION}, {@link #INFIX} and {@link #POSTFIX}.
171 * @param min Minimum number of arguments for this operator.
172 * @param max Maximum number of arguments for this operator.
173 */
174 public Operator(final String startSymbol, final String separatorSymbol, final String endSymbol,
175 final String qedeq,
176 final String qedeqArgument,
177 final int priority,
178 final int type,
179 final int min,
180 final int max) {
181 this.startSymbol = startSymbol;
182 this.separatorSymbol = separatorSymbol;
183 this.endSymbol = endSymbol;
184 this.type = type;
185 this.qedeq = qedeq;
186 this.qedeqArgument = qedeqArgument;
187 this.priority = priority;
188 this.min = min;
189 this.max = max;
190 switch (type) {
191 case INFIX:
192 case SIMPLE_PREFIX:
193 case FUNCTION:
194 case POSTFIX:
195 break;
196 default:
197 throw new IllegalArgumentException("unknown operator type: "
198 + type);
199 }
200 if (max != -1 && min > max) {
201 throw new IllegalArgumentException("Min greater than max: " + min + " > " + max);
202 }
203 if (isInfix() && min < 2) {
204 throw new IllegalArgumentException("Infix needs at least two arguments");
205 }
206 }
207
208 /**
209 * Returns symbol or token to identify this operator.
210 *
211 * @return Symbol or token to identify a start of this operator.
212 */
213 public final String getStartSymbol() {
214 return startSymbol;
215 }
216
217 /**
218 * Returns symbol or token to separate different arguments for this operator. Can only be
219 * different from <code>null</code> if this is a prefix operator.
220 *
221 * @return Symbol or token to identify the start of a new argument of this operator.
222 */
223 public String getSeparatorSymbol() {
224 return separatorSymbol;
225 }
226
227 /**
228 * Returns symbol or token to identify the end of this operator. Can only be different from
229 * <code>null</code> if this is a prefix operator.
230 *
231 * @return Symbol or token to identify the end of this operator. Maybe <code>null</code>.
232 */
233 public String getEndSymbol() {
234 return endSymbol;
235 }
236
237 /**
238 * Is this an infix operator?
239 *
240 * @return Is this an infix operator?
241 */
242 public final boolean isInfix() {
243 return type == INFIX;
244 }
245
246 /**
247 * Is this a prefix operator?
248 *
249 * @return Is this a prefix operator?
250 */
251 public final boolean isPrefix() {
252 return type == SIMPLE_PREFIX || type == FUNCTION;
253 }
254
255 /**
256 * Is this a function operator?
257 *
258 * @return Is this a function operator?
259 */
260 public final boolean isFunction() {
261 return type == FUNCTION;
262 }
263
264 /**
265 * Is this a postfix operator?
266 *
267 * @return Is this a postfix operator?
268 */
269 public final boolean isPostfix() {
270 return type == POSTFIX;
271 }
272
273 /**
274 * Get operator priority. 0 is the highest priority.
275 *
276 * @return Priority.
277 */
278 public final int getPriority() {
279 return this.priority;
280 }
281
282 /**
283 * Get minimum argument number.
284 *
285 * @return Minimum argument number.
286 */
287 public final int getMin() {
288 return this.min;
289 }
290
291 /**
292 * Get maximum argument number.
293 *
294 * @return Maximum argument number.
295 */
296 public final int getMax() {
297 return max;
298 }
299
300 /**
301 * Get QEDEQ operator name.
302 *
303 * @return QEDEQ operator name.
304 */
305 public final String getQedeq() {
306 return qedeq;
307 }
308
309 /**
310 * Get first QEDEQ argument.
311 *
312 * @return First QEDEQ argument. Can be <code>null</code>.
313 */
314 public final String getQedeqArgument() {
315 return qedeqArgument;
316 }
317
318 public final String toString() {
319 final StringBuffer buffer = new StringBuffer(getStartSymbol());
320 buffer.append("[" + getMin() + ", ");
321 if (getMax() == -1) {
322 buffer.append("..");
323 } else {
324 buffer.append(getMax());
325 }
326 buffer.append("]");
327 if (getSeparatorSymbol() != null) {
328 buffer.append(" ").append(getSeparatorSymbol());
329 }
330 if (getEndSymbol() != null) {
331 buffer.append(" ").append(getEndSymbol());
332 }
333 if (isFunction()) {
334 buffer.append(", is function");
335 }
336 if (isPrefix()) {
337 buffer.append(", is prefix");
338 }
339 if (isInfix()) {
340 buffer.append(", is infix");
341 }
342 if (isPostfix()) {
343 buffer.append(", is postfix");
344 }
345 return buffer.toString();
346 }
347
348 }
|