Operator.java
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 != -&& 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 }