Пример #1
0
 /**
  * Die Methode führt die Kontextanalyse für diesen Ausdruck durch. Dabei wird ein Zugriff über
  * SELF in den Syntaxbaum eingefügt, wenn dieser Ausdruck ein Attribut oder eine Methode
  * bezeichnet. Diese Methode wird niemals für Ausdrücke aufgerufen, die rechts vom
  * Objekt-Zugriffsoperator stehen.
  *
  * @param declarations Die an dieser Stelle gültigen Deklarationen.
  * @return Dieser Ausdruck oder ein neuer Ausdruck, falls ein Boxing oder der Zugriff über SELF
  *     eingefügt wurde.
  * @throws CompileException Während der Kontextanylyse wurde ein Fehler gefunden.
  */
 Expression contextAnalysis(Declarations declarations) throws CompileException {
   contextAnalysisForMember(declarations);
   if (identifier.declaration instanceof MethodDeclaration
       || identifier.declaration instanceof VarDeclaration
           && ((VarDeclaration) identifier.declaration).isAttribute) {
     AccessExpression a =
         new AccessExpression(new VarOrCall(new ResolvableIdentifier("_self", position)), this);
     a.leftOperand = a.leftOperand.contextAnalysis(declarations);
     a.leftOperand = a.leftOperand.box(declarations);
     a.type = type;
     a.lValue = lValue;
     /** BEGIN Ausgabe (f): Methoden Parameter */
     contextAnalysisForParameters(declarations);
     /** END Aufgabe (f) */
     return a;
   } else {
     return this;
   }
 }
Пример #2
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;
 }