Пример #1
0
 @Override
 public Void visitBinaryExpression(BinaryExpression node) {
   visit(node.getLeftOperand());
   writer.print(' ');
   writer.print(node.getOperator().getLexeme());
   writer.print(' ');
   visit(node.getRightOperand());
   return null;
 }
Пример #2
0
  // Parses a binary expression
  private void parse(BinaryExpression be) {
    BinaryOperator bop = be.getOperator();
    SimpleExpression lhs = new SimpleExpression(be.getLHS());
    SimpleExpression rhs = new SimpleExpression(be.getRHS());
    contains_side_effect |= (lhs.contains_side_effect || rhs.contains_side_effect);

    if (bop == BinaryOperator.SUBTRACT) {
      sop = ADD;
      SimpleExpression new_rhs = new SimpleExpression(MUL);
      new_rhs.add(getInt(-1));
      new_rhs.add(rhs);
      add(lhs);
      add(new_rhs);
    } else {
      sop = cop.indexOf(bop);
      if (sop == -1) {
        sop = TREE;
        expr = be;
      }
      add(lhs);
      add(rhs);
    }
  }
 public void visit(BinaryExpression entity) {
   wGetVisitor1().visit(entity.getLeftExpr());
   wGetVisitor1().visit(entity.getOperator());
   wGetVisitor1().visit(entity.getRightExpr());
 }
Пример #4
0
 /** Normalization for points-to analysis. */
 private static Expression normalize(Expression arg, Symbol param) {
   Expression ret = arg.clone(); // default behavior.
   // Converts array accesses to address-of expressions.
   if (ret instanceof ArrayAccess) {
     ArrayAccess array = (ArrayAccess) ret;
     // Normalize the array name.
     Expression name = normalize(array.getArrayName(), null);
     Symbol base = SymbolTools.getSymbolOf(name);
     if (base != null && param != null && SymbolTools.isPointerParameter(param)) {
       // case 1: the base symbol has an array specifier.
       // --> - keeps the array indices while adding trailing [0].
       //     - converts to address-of expression.
       //     - adds dereference operator if base is a formal parameter
       if (SymbolTools.isArray(base)) {
         // Adds a trailing subscript "[0]" intentionally.
         array.addIndex(new IntegerLiteral(0));
         ret = new UnaryExpression(UnaryOperator.ADDRESS_OF, ret);
         // Formal parameter is normalized: a[10] to (*a)[10].
         // This conversion is used only internally (not legal in C).
         if (SymbolTools.isPointerParameter(base)) {
           array
               .getArrayName()
               .swapWith(new UnaryExpression(UnaryOperator.DEREFERENCE, name.clone()));
         }
         // case 2: the base symbol does not have an array specifier.
         // --> just take the base object while converting a subscript
         // to a dereference.
       } else {
         ret = name;
         for (int i = 0; i < array.getNumIndices(); i++) {
           ret = new UnaryExpression(UnaryOperator.DEREFERENCE, ret.clone());
         }
       }
     } else { // just normalizes the array name.
       array.getArrayName().swapWith(name);
     }
     // Removes pointer access and adds trailing dummy index for pointer
     // type.
   } else if (ret instanceof AccessExpression) {
     AccessExpression access = (AccessExpression) ret;
     // POINTER_ACCESS to MEMBER_ACCESS
     if (access.getOperator() == AccessOperator.POINTER_ACCESS) {
       // Normalize the LHS.
       Expression lhs = normalize(access.getLHS(), null);
       ret =
           new AccessExpression(
               new UnaryExpression(UnaryOperator.DEREFERENCE, lhs.clone()),
               AccessOperator.MEMBER_ACCESS,
               access.getRHS().clone());
     }
     // Pointer type to address-of expression.
     if (param != null && SymbolTools.isPointerParameter(param)) {
       ret =
           new UnaryExpression(
               UnaryOperator.ADDRESS_OF, new ArrayAccess(ret.clone(), new IntegerLiteral(0)));
     }
     // Just normalize the expression child.
   } else if (ret instanceof UnaryExpression) {
     UnaryExpression ue = (UnaryExpression) ret;
     ue.setExpression(normalize(ue.getExpression(), null));
     // Tries to convert simple pointer arithmetic to array access.
   } else if (ret instanceof BinaryExpression) {
     BinaryExpression be = (BinaryExpression) ret;
     Expression lhs = normalize(be.getLHS(), null);
     Expression rhs = normalize(be.getRHS(), null);
     if (param != null
         && SymbolTools.isPointerParameter(param)
         && be.getOperator() == BinaryOperator.ADD) {
       if (isPointerArithmeticOperand(lhs, rhs)) {
         ret =
             new UnaryExpression(
                 UnaryOperator.ADDRESS_OF, new ArrayAccess(rhs.clone(), lhs.clone()));
       } else if (isPointerArithmeticOperand(rhs, lhs)) {
         ret =
             new UnaryExpression(
                 UnaryOperator.ADDRESS_OF, new ArrayAccess(lhs.clone(), rhs.clone()));
       }
     } else {
       ret = new BinaryExpression(lhs.clone(), be.getOperator(), rhs.clone());
     }
     // Type cast is discarded.
   } else if (ret instanceof Typecast) {
     ret = (Expression) ret.getChildren().get(0);
   }
   return ret;
 }
Пример #5
0
 @SuppressWarnings("unchecked")
 @Override
 public Function<Object[], ?> visit(BinaryExpression e) {
   final Function<Object[], ?> first = e.getFirst().accept(this);
   final Function<Object[], ?> second = e.getSecond().accept(this);
   switch (e.getExpressionType()) {
     case ExpressionType.Add:
       return normalize(
           add((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.BitwiseAnd:
       return normalize(
           bitwiseAnd((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LogicalAnd:
       return normalize(
           and((Function<Object[], Boolean>) first, (Function<Object[], Boolean>) second));
     case ExpressionType.ArrayIndex:
       return t -> Array.get(first.apply(t), (Integer) second.apply(t));
       // return new Function<Object, Object[]>() {
       // // @Override
       // public Object invoke(Object[] t) throws Throwable {
       // return Array.get(first.invoke(t), (Integer) second
       // .invoke(t));
       // }
       // };
       // case ExpressionType.Coalesce:
       // return coalesce((Function<?, Object[]>) first,
       // (Function<?, Object[]>) second);
     case ExpressionType.Conditional:
       return iif((Function<Object[], Boolean>) e.getOperator().accept(this), first, second);
     case ExpressionType.Divide:
       return normalize(
           divide((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.Equal:
       return normalize(equal(first, second));
     case ExpressionType.ExclusiveOr:
       return normalize(
           xor((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.GreaterThan:
       return normalize(
           greaterThan((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.GreaterThanOrEqual:
       return normalize(
           greaterThanOrEqual(
               (Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LeftShift:
       return normalize(
           shiftLeft((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LessThan:
       return normalize(
           lessThan((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LessThanOrEqual:
       return normalize(
           lessThanOrEqual(
               (Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.Modulo:
       return normalize(
           modulo((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.Multiply:
       return normalize(
           multiply((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.NotEqual:
       return normalize(equal(first, second).negate());
     case ExpressionType.BitwiseOr:
       return normalize(
           bitwiseOr((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.LogicalOr:
       return normalize(
           or((Function<Object[], Boolean>) first, (Function<Object[], Boolean>) second));
       // case ExpressionType.Power:
       // return power((Function<Number, Object[]>) first,
       // (Function<Number, Object[]>) second);
     case ExpressionType.RightShift:
       return normalize(
           shiftRight((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.Subtract:
       return normalize(
           subtract((Function<Object[], Number>) first, (Function<Object[], Number>) second));
     case ExpressionType.InstanceOf:
       return normalize(instanceOf(first, (Class<?>) second.apply(null)));
     default:
       throw new IllegalArgumentException(ExpressionType.toString(e.getExpressionType()));
   }
 }