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