@Test public void operationChangeRequiresAssociativityRestoration() { BinExpr target; ExprContainer container = new ExprContainer(); container.expr.set(target = mul(id(), mul(id(), id()))); new ExprBinOpTransformer().balanceOnOperationChange(target); assertEquals("((id '*' id) '*' id)", container.expr.get().toString()); }
public ExprT balanceOnOperationChange(BinExprT expr) { int exprPriority = getPriority(expr); ExprT left = left(expr).get(); ExprT right = right(expr).get(); Associativity assoc = getAssociativity(expr); if (isBinOp(left)) { BinExprT leftExpr = asBinOp(left); int leftPriority = getPriority(leftExpr); if ((assoc == Associativity.LEFT && leftPriority < exprPriority) || (assoc == Associativity.RIGHT && leftPriority <= exprPriority)) { expr = balanceDown(expr); } } else if (isBinOp(right)) { BinExprT rightExpr = asBinOp(right); int rightPriority = getPriority(rightExpr); if ((assoc == Associativity.LEFT && rightPriority >= exprPriority) || (assoc == Associativity.RIGHT && rightPriority > exprPriority)) { expr = balanceDown(expr); } } ExprT parent = parent(expr); assoc = getAssociativity(expr); if (isBinOp(parent)) { BinExprT parentExpr = asBinOp(parent); int parentPriority = getPriority(parentExpr); boolean isLeft = left == left(parentExpr).get(); if (isLeft && (assoc == Associativity.LEFT && exprPriority < parentPriority) || (assoc == Associativity.RIGHT && exprPriority <= parentPriority)) { return balanceUp(expr); } if (!isLeft && (assoc == Associativity.LEFT && exprPriority <= parentPriority) || (assoc == Associativity.RIGHT && exprPriority < parentPriority)) { return balanceUp(expr); } } return expr; }
BinOpTransformer { public ExprT balanceOnOperationChange(BinExprT expr) { int exprPriority = getPriority(expr); ExprT left = left(expr).get(); ExprT right = right(expr).get(); Associativity assoc = getAssociativity(expr); if (isBinOp(left)) { BinExprT leftExpr = asBinOp(left); int leftPriority = getPriority(leftExpr); if ((assoc == Associativity.LEFT && leftPriority < exprPriority) || (assoc == Associativity.RIGHT && leftPriority <= exprPriority)) { expr = balanceDown(expr); } } else if (isBinOp(right)) { BinExprT rightExpr = asBinOp(right); int rightPriority = getPriority(rightExpr); if ((assoc == Associativity.LEFT && rightPriority >= exprPriority) || (assoc == Associativity.RIGHT && rightPriority > exprPriority)) { expr = balanceDown(expr); } } ExprT parent = parent(expr); assoc = getAssociativity(expr); if (isBinOp(parent)) { BinExprT parentExpr = asBinOp(parent); int parentPriority = getPriority(parentExpr); boolean isLeft = left == left(parentExpr).get(); if (isLeft && (assoc == Associativity.LEFT && exprPriority < parentPriority) || (assoc == Associativity.RIGHT && exprPriority <= parentPriority)) { return balanceUp(expr); } if (!isLeft && (assoc == Associativity.LEFT && exprPriority <= parentPriority) || (assoc == Associativity.RIGHT && exprPriority < parentPriority)) { return balanceUp(expr); } } return expr; } }
BinOpTransformer { public ExprT balanceOnOperationChange(BinExprT expr) { int exprPriority = getPriority(expr); ExprT left = left(expr).get(); ExprT right = right(expr).get(); Associativity assoc = getAssociativity(expr); if (isBinOp(left)) { BinExprT leftExpr = asBinOp(left); int leftPriority = getPriority(leftExpr); if ((assoc == Associativity.LEFT && leftPriority < exprPriority) || (assoc == Associativity.RIGHT && leftPriority <= exprPriority)) { expr = balanceDown(expr); } } else if (isBinOp(right)) { BinExprT rightExpr = asBinOp(right); int rightPriority = getPriority(rightExpr); if ((assoc == Associativity.LEFT && rightPriority >= exprPriority) || (assoc == Associativity.RIGHT && rightPriority > exprPriority)) { expr = balanceDown(expr); } } ExprT parent = parent(expr); assoc = getAssociativity(expr); if (isBinOp(parent)) { BinExprT parentExpr = asBinOp(parent); int parentPriority = getPriority(parentExpr); boolean isLeft = left == left(parentExpr).get(); if (isLeft && (assoc == Associativity.LEFT && exprPriority < parentPriority) || (assoc == Associativity.RIGHT && exprPriority <= parentPriority)) { return balanceUp(expr); } if (!isLeft && (assoc == Associativity.LEFT && exprPriority <= parentPriority) || (assoc == Associativity.RIGHT && exprPriority < parentPriority)) { return balanceUp(expr); } } return expr; }  }
BinOpTransformer { public ExprT balanceOnOperationChange(BinExprT expr) { int exprPriority = getPriority(expr); ExprT left = left(expr).get(); ExprT right = right(expr).get(); Associativity assoc = getAssociativity(expr); if (isBinOp(left)) { BinExprT leftExpr = asBinOp(left); int leftPriority = getPriority(leftExpr); if ((assoc == Associativity.LEFT && leftPriority < exprPriority) || (assoc == Associativity.RIGHT && leftPriority <= exprPriority)) { expr = balanceDown(expr); } } else if (isBinOp(right)) { BinExprT rightExpr = asBinOp(right); int rightPriority = getPriority(rightExpr); if ((assoc == Associativity.LEFT && rightPriority >= exprPriority) || (assoc == Associativity.RIGHT && rightPriority > exprPriority)) { expr = balanceDown(expr); } } ExprT parent = parent(expr); assoc = getAssociativity(expr); if (isBinOp(parent)) { BinExprT parentExpr = asBinOp(parent); int parentPriority = getPriority(parentExpr); boolean isLeft = left == left(parentExpr).get(); if (isLeft && (assoc == Associativity.LEFT && exprPriority < parentPriority) || (assoc == Associativity.RIGHT && exprPriority <= parentPriority)) { return balanceUp(expr); } if (!isLeft && (assoc == Associativity.LEFT && exprPriority <= parentPriority) || (assoc == Associativity.RIGHT && exprPriority < parentPriority)) { return balanceUp(expr); } } return expr; }  BinExprT balanceUp(BinExprT expr); ExprT balanceOnOperationChange(BinExprT expr); BinExprT balanceDown(BinExprT expr); }
BinOpTransformer { public ExprT balanceOnOperationChange(BinExprT expr) { int exprPriority = getPriority(expr); ExprT left = left(expr).get(); ExprT right = right(expr).get(); Associativity assoc = getAssociativity(expr); if (isBinOp(left)) { BinExprT leftExpr = asBinOp(left); int leftPriority = getPriority(leftExpr); if ((assoc == Associativity.LEFT && leftPriority < exprPriority) || (assoc == Associativity.RIGHT && leftPriority <= exprPriority)) { expr = balanceDown(expr); } } else if (isBinOp(right)) { BinExprT rightExpr = asBinOp(right); int rightPriority = getPriority(rightExpr); if ((assoc == Associativity.LEFT && rightPriority >= exprPriority) || (assoc == Associativity.RIGHT && rightPriority > exprPriority)) { expr = balanceDown(expr); } } ExprT parent = parent(expr); assoc = getAssociativity(expr); if (isBinOp(parent)) { BinExprT parentExpr = asBinOp(parent); int parentPriority = getPriority(parentExpr); boolean isLeft = left == left(parentExpr).get(); if (isLeft && (assoc == Associativity.LEFT && exprPriority < parentPriority) || (assoc == Associativity.RIGHT && exprPriority <= parentPriority)) { return balanceUp(expr); } if (!isLeft && (assoc == Associativity.LEFT && exprPriority <= parentPriority) || (assoc == Associativity.RIGHT && exprPriority < parentPriority)) { return balanceUp(expr); } } return expr; }  BinExprT balanceUp(BinExprT expr); ExprT balanceOnOperationChange(BinExprT expr); BinExprT balanceDown(BinExprT expr);  }