View Javadoc

1   /* This file is part of the project "Hilbert II" - http://www.qedeq.org" target="alexandria_uri">http://www.qedeq.org
2    *
3    * Copyright 2000-2014,  Michael Meyling <mime@qedeq.org>.
4    *
5    * "Hilbert II" is free software; you can redistribute
6    * it and/or modify it under the terms of the GNU General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU General Public License for more details.
14   */
15  
16  package org.qedeq.kernel.bo.parser;
17  
18  
19  /**
20   * This class describes an term or logical operator. An operator is of either
21   * prefix, infix or postfix type and has a minimum and maximum number of operands.
22   * It has a symbol or token that enables to recognize it and a QEDEQ representation.
23   * Each instance of this class is unique so two instances with the same parameters are
24   * different from each other.
25   *
26   * @author  Michael Meyling
27   */
28  public final class Operator {
29  
30      /** Marks infix operator. */
31      public static final int INFIX = 0;
32  
33      /** Marks prefix operator. */
34      public static final int SIMPLE_PREFIX = 1;
35  
36      /** Marks postfix operator. */
37      public static final int POSTFIX = 2;
38  
39      /** Marks function operator. */
40      public static final int FUNCTION = 4;
41  
42      /** Prefix, function, infix or postfix. See {@link #SIMPLE_PREFIX}, {@link #FUNCTION},
43       * {@link #INFIX} and {@link #POSTFIX}. */
44      private final int type;
45  
46      /** Start symbol or token for this operator. */
47      private final String startSymbol;
48  
49      /** Separator symbol or token for this operator. This could be a comma for example. */
50      private final String separatorSymbol;
51  
52      /** End symbol or token for this operator. */
53      private final String endSymbol;
54  
55      /** Operator priority. Highest is 0. */
56      private final int priority;
57  
58      /** QEDEQ token for this operator. */
59      private final String qedeq;
60  
61      /** First QEDEQ argument. Can be <code>null</code>. */
62      private final String qedeqArgument;
63  
64      /** Minimum number of arguments. */
65      private final int min;
66  
67      /** Maximum number of arguments. */
68      private final int max;
69  
70  
71      /**
72       * Constructor.
73       *
74       * @param   symbol      Symbol or token for this operator.
75       * @param   qedeq       QEDEQ operator symbol.
76       * @param   qedeqArgument       First Argument in QEDEQ-Syntax - if any.
77       * @param   priority    Operator priority, highest is 0.
78       * @param   type        Prefix, infix or postfix. See {@link #SIMPLE_PREFIX}, {@link #FUNCTION},
79       *                      {@link #INFIX} and {@link #POSTFIX}.
80       * @param   min         Minimum number of arguments for this operator.
81       */
82      public Operator(final String symbol,
83               final String qedeq,
84               final String qedeqArgument,
85               final int priority,
86               final int type,
87               final int min) {
88          this(symbol, qedeq, qedeqArgument, priority, type, min, -1);
89      }
90  
91      /**
92       * Constructor.
93       *
94       * @param   symbol              Symbol or token for this operator.
95       * @param   qedeq               QEDEQ operator symbol.
96       * @param   qedeqArgument       First Argument in QEDEQ-Syntax - if any.
97       * @param   priority            Operator priority, highest is 0.
98       * @param   type                Prefix, infix or postfix. See {@link #SIMPLE_PREFIX},
99       *                              {@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 }
349