package de.gaalop.clucalc.output; import de.gaalop.dfg.*; import java.util.HashMap; import java.util.Map; /** * Models the priority of different operators. Two expressions can be compared using the * {@link #hasLowerPriority(Expression, Expression)} method. This is important since parenthesis * have to be introduced if necessary. */ public class OperatorPriority { private static final Map<Class<? extends Expression>, Integer> OPERATOR_PRIORITY; static { OPERATOR_PRIORITY = new HashMap<Class<? extends Expression>, Integer>(); // Operator priority from high to low OPERATOR_PRIORITY.put(BaseVector.class, 1000); OPERATOR_PRIORITY.put(FloatConstant.class, 1000); OPERATOR_PRIORITY.put(Variable.class, 1000); OPERATOR_PRIORITY.put(MultivectorComponent.class, 1000); OPERATOR_PRIORITY.put(MathFunctionCall.class, 1000); OPERATOR_PRIORITY.put(Negation.class, 990); OPERATOR_PRIORITY.put(Exponentiation.class, 985); OPERATOR_PRIORITY.put(OuterProduct.class, 980); OPERATOR_PRIORITY.put(InnerProduct.class, 970); OPERATOR_PRIORITY.put(Multiplication.class, 960); OPERATOR_PRIORITY.put(Division.class, 960); OPERATOR_PRIORITY.put(Subtraction.class, 950); OPERATOR_PRIORITY.put(Addition.class, 940); OPERATOR_PRIORITY.put(Relation.class, 930); OPERATOR_PRIORITY.put(LogicalAnd.class, 930); OPERATOR_PRIORITY.put(LogicalOr.class, 930); OPERATOR_PRIORITY.put(Equality.class, 920); OPERATOR_PRIORITY.put(Inequality.class, 920); } /** * Checks whether a child expression has a lower priority than the parent expression and needs to * be put into parenthesis. * * @param parent The parent expression that contains the child expression. * @param child The child expression that will be output. * @return True if parenthesis need to be used. */ public static boolean hasLowerPriority(Expression parent, Expression child) { Integer parentPriority = OPERATOR_PRIORITY.get(parent.getClass()); Integer childPriority = OPERATOR_PRIORITY.get(child.getClass()); // Default to parenthesis for unknown combinations if (parentPriority == null || childPriority == null) { return true; } else { return childPriority < parentPriority; } } }