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