diff --git a/Parser/spec/AccPrinting.jadd b/Parser/spec/AccPrinting.jadd
index 99738449bdfa61bfa78b791e82583752fd5e31c6..9f784bbe3097a8e6c75736d735f230d7bd670588 100644
--- a/Parser/spec/AccPrinting.jadd
+++ b/Parser/spec/AccPrinting.jadd
@@ -15,8 +15,10 @@ aspect Printing {
   // AccParallelStmt:AccStmt ::= AccClause* ;
   public void AccParallelStmt.prettyPrint(PrettyPrinter s) {
     s.append("!$acc parallel");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -37,8 +39,10 @@ aspect Printing {
   // AccKernelsStmt:AccStmt ::= AccClause* ;
   public void AccKernelsStmt.prettyPrint(PrettyPrinter s) {
     s.append("!$acc kernels");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -60,8 +64,10 @@ aspect Printing {
   // AccDataStmt:AccStmt ::= AccClause* ;
   public void AccDataStmt.prettyPrint(PrettyPrinter s) {
     s.append("!$acc data");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -82,8 +88,10 @@ aspect Printing {
   // AccHostDataStmt:AccStmt ::= AccClause* ;
   public void AccHostDataStmt.prettyPrint(PrettyPrinter s) {
     s.append("!$acc host_data");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -155,8 +163,10 @@ aspect Printing {
   // AccLoopStmt:AccStmt ::= AccClause* ;
   public void AccLoopStmt.prettyPrint(PrettyPrinter s) {
     s.append("!$acc loop");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -179,8 +189,10 @@ aspect Printing {
   // AccParallelLoopStmt:AccStmt ::= AccClause* ;
   public void AccParallelLoopStmt.prettyPrint(PrettyPrinter s) {
     s.append("!$acc parallel loop");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -202,8 +214,10 @@ aspect Printing {
   // AccKernelsLoopStmt:AccStmt ::= AccClause* ;
   public void AccKernelsLoopStmt.prettyPrint(PrettyPrinter s) {
     s.append("!$acc kernels loop");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -219,34 +233,39 @@ aspect Printing {
   // AccEnterDataDirective:AccDirective ::= AccClause* ;
   public void AccEnterDataDirective.prettyPrint(PrettyPrinter s) {
     s.append("!$acc enter data");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
   // AccExitDataDirective:AccDirective ::= AccClause* ;
   public void AccExitDataDirective.prettyPrint(PrettyPrinter s) {
     s.append("!$acc exit data");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
   // ACC 2.10
   // AccCacheDirective:AccDirective ::= Variable* ;
   public void AccCacheDirective.prettyPrint(PrettyPrinter s) {
-    s.append("!$acc cache");
-    s.ensureWs();
-    getVariableList().prettyPrintJoin(s, ", ");
-    s.lb();
+    s.append("!$acc cache").append("(");
+    getVariableList().prettyPrintJoin(s, ",");
+    s.append(")").lb();
   }
 
   // ACC 2.14.4
   // AccUpdateDirective:AccDirective ::= AccClause* ;
   public void AccUpdateDirective.prettyPrint(PrettyPrinter s) {
     s.append("!$acc update");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -254,8 +273,10 @@ aspect Printing {
   // AccDeclareDirective:AccDirective ::= AccClause* ;
   public void AccDeclareDirective.prettyPrint(PrettyPrinter s) {
     s.append("!$acc declare");
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -268,8 +289,10 @@ aspect Printing {
       getName().prettyPrint(s);
       s.append(")");
     }
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -279,11 +302,13 @@ aspect Printing {
     s.append("!$acc wait");
     if (getExprList().numChildren() > 0) {
       s.append("(");
-      getExprList().prettyPrintJoin(s, ", ");
+      getExprList().prettyPrintJoin(s, ",");
       s.append(")");
     }
-    s.ensureWs();
-    getAccClauseList().prettyPrintJoin(s, " ");
+    for (AccClause clause : getAccClauseList()) {
+      s.append(" ");
+      clause.prettyPrint(s);
+    }
     s.lb();
   }
 
@@ -301,7 +326,7 @@ aspect Printing {
     s.append("reduction(");
     getAccOperator().prettyPrint(s);
     s.append(":");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
@@ -321,97 +346,97 @@ aspect Printing {
 
   public void AccCopyClause.prettyPrint(PrettyPrinter s) {
     s.append("copy(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccCopyInClause.prettyPrint(PrettyPrinter s) {
     s.append("copyin(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccCopyOutClause.prettyPrint(PrettyPrinter s) {
     s.append("copyout(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccCreateClause.prettyPrint(PrettyPrinter s) {
     s.append("create(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccDeleteClause.prettyPrint(PrettyPrinter s) {
     s.append("delete(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccDeviceClause.prettyPrint(PrettyPrinter s) {
     s.append("device(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccSelfClause.prettyPrint(PrettyPrinter s) {
     s.append("self(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccHostClause.prettyPrint(PrettyPrinter s) {
     s.append("host(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccFirstPrivateClause.prettyPrint(PrettyPrinter s) {
     s.append("firstprivate(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccPresentOrCopyClause.prettyPrint(PrettyPrinter s) {
     s.append("present_or_copy(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccPresentClause.prettyPrint(PrettyPrinter s) {
     s.append("present(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccPresentOrCopyInClause.prettyPrint(PrettyPrinter s) {
     s.append("present_or_copyin(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccPresentOrCopyOutClause.prettyPrint(PrettyPrinter s) {
     s.append("present_or_copyout(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccPresentOrCreateClause.prettyPrint(PrettyPrinter s) {
     s.append("present_or_create(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccPrivateClause.prettyPrint(PrettyPrinter s) {
     s.append("private(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccUseDeviceClause.prettyPrint(PrettyPrinter s) {
     s.append("use_device(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
@@ -425,19 +450,19 @@ aspect Printing {
 
   public void AccDeviceTypeListClause.prettyPrint(PrettyPrinter s) {
     s.append("device_type(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccTileClause.prettyPrint(PrettyPrinter s) {
     s.append("tile(");
-    getExprList().prettyPrintJoin(s, ", ");
+    getExprList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccWaitClause.prettyPrint(PrettyPrinter s) {
     s.append("wait(");
-    getExprList().prettyPrintJoin(s, ", ");
+    getExprList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
@@ -476,9 +501,9 @@ aspect Printing {
   }
 
   public void AccGangClause.prettyPrint(PrettyPrinter s) {
-    if (hasNumGangs()) {
+    if (hasNum()) {
       s.append("gang(");
-      getNumGangs().prettyPrint(s);
+      getNum().prettyPrint(s);
       s.append(")");
     } else {
       s.append("gang");
@@ -486,9 +511,9 @@ aspect Printing {
   }
 
   public void AccWorkerClause.prettyPrint(PrettyPrinter s) {
-    if (hasNumWorkers()) {
+    if (hasNum()) {
       s.append("worker(");
-      getNumWorkers().prettyPrint(s);
+      getNum().prettyPrint(s);
       s.append(")");
     } else {
       s.append("worker");
@@ -496,9 +521,9 @@ aspect Printing {
   }
 
   public void AccVectorClause.prettyPrint(PrettyPrinter s) {
-    if (hasVectorLength()) {
+    if (hasNum()) {
       s.append("vector(");
-      getVectorLength().prettyPrint(s);
+      getNum().prettyPrint(s);
       s.append(")");
     } else {
       s.append("vector");
@@ -507,13 +532,13 @@ aspect Printing {
 
   public void AccDeviceResidentClause.prettyPrint(PrettyPrinter s) {
     s.append("device_resident(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
   public void AccLinkClause.prettyPrint(PrettyPrinter s) {
     s.append("link(");
-    getVariableList().prettyPrintJoin(s, ", ");
+    getVariableList().prettyPrintJoin(s, ",");
     s.append(")");
   }
 
diff --git a/Parser/spec/Fortran2008.rats b/Parser/spec/Fortran2008.rats
index eb189fcade8c611d807fe1683dafd11e5b05c620..bbe8c1ed8644e97b408f07a0a50f02e47371f28a 100644
--- a/Parser/spec/Fortran2008.rats
+++ b/Parser/spec/Fortran2008.rats
@@ -3049,14 +3049,15 @@ Allocation allocation =
 //// VariableAllocateObject:AllocateObject ::= VariableName ;
 //// StructureComponentAllocateObject:AllocateObject ::= StructureComponent ;
 AllocateObject allocate_object =
-    n:name
+    s:structure_component
         {
-            yyValue = new NameAllocateObject(n);
+            yyValue = new StructureComponentAllocateObject(s);
         }
-/   s:structure_component
+/   n:name
         {
-            yyValue = new StructureComponentAllocateObject(s);
+            yyValue = new NameAllocateObject(n);
         }
+
 ;
 
 //// // R633
diff --git a/Parser/spec/Fortran2008Rewrites.jrag b/Parser/spec/Fortran2008Rewrites.jrag
index 6a4fd68384077d5ba766bafb70d0af0a2270e32d..751f7ef97e973a83df22fa2dcf2758436b05a8e2 100644
--- a/Parser/spec/Fortran2008Rewrites.jrag
+++ b/Parser/spec/Fortran2008Rewrites.jrag
@@ -27,42 +27,6 @@ aspect AmbiguityResoler {
   //   }
   // }
 
-  rewrite AccLoopStmt {
-    when (containedCollapseOne() != null)
-    to AccLoopStmt {
-      ASTNode parent = getParent();
-      if(parent!=null){
-        int i = containedCollapseOne().getParent().getIndexOfChild(containedCollapseOne());
-        if(i>-1){
-          parent.removeChild(i);
-        }
-
-      }
-      return this;
-    }
-  }
-
-  // TODO support the collapse optimisation in all Acc Statements
-  syn AccCollapseClause AccStmt.containedCollapseOne();
-  eq AccStmt.containedCollapseOne() = null;
-  eq AccLoopStmt.containedCollapseOne() {
-    for (AccClause clause: getAccClauseList()) {
-      if (clause.isCollapseOne() != null) {
-        return clause.isCollapseOne();
-      }
-    }
-    return null;
-  }
-
-  syn AccCollapseClause AccClause.isCollapseOne();
-  eq AccClause.isCollapseOne() = null;
-  eq AccCollapseClause.isCollapseOne() {
-    if (getCount().getDigitString().getDigits().equals("1")) {
-      return this;
-    } else {
-      return null;
-    }
-  }
 
   /**
    * C624 (R618) Exactly one part-ref shall have nonzero rank, and either the final part-ref shall
diff --git a/Parser/spec/OpenAcc.rats b/Parser/spec/OpenAcc.rats
index 87ca2bd306d21b7c0b74bc81702f8735ff99f2e3..086829102f5bc900ca70802a4c88808edd5ef572 100644
--- a/Parser/spec/OpenAcc.rats
+++ b/Parser/spec/OpenAcc.rats
@@ -33,9 +33,13 @@ List<Variable> var_list =
 ;
 
 List<Variable> p_var_list =
-    LPAREN vl:(COMMA yyValue:variable)* RPAREN
+    LPAREN v:variable vl:(COMMA yyValue:variable)* RPAREN
         {
-            yyValue = new List().addAll(vl.list());
+            yyValue = new List().add(v).addAll(vl.list());
+        }
+/   LPAREN RPAREN
+        {
+            yyValue = new List();
         }
 ;
 
@@ -49,7 +53,7 @@ List<Expr> expr_list =
 //// // An AccStmt does not have a label or a comment (unlike Fortran statements).
 //// // It must, however, begin with ""!$acc" and end with a line break
 //// abstract AccStmt ;
-//// abstract AccAbstractDataStmt ::= AccClause* ;
+//// abstract AccAbstractDataStmt:AccStmt ::= AccClause* ;
 
 // constructs ------------------------------------------------------------------
 
@@ -549,7 +553,7 @@ AccCopyClause acc_copy_clause =
 ;
 
 //// AccCopyInClause:AccDataClause ;
-//// AccPresentOrCopyInClause:AccCopyClause ;
+//// AccPresentOrCopyInClause:AccCopyInClause ;
 AccCopyInClause acc_copyin_clause =
 	A_COPYIN list:p_var_list
 		{
@@ -562,8 +566,8 @@ AccCopyInClause acc_copyin_clause =
 ;
 
 //// AccCopyOutClause:AccDataClause ;
-//// AccPresentOrCopyOutClause:AccCopyClause ;
-AccCopyOutClause acc_copyin_clause =
+//// AccPresentOrCopyOutClause:AccCopyOutClause ;
+AccCopyOutClause acc_copyout_clause =
 	A_COPYOUT list:p_var_list
 		{
 			yyValue = new AccCopyOutClause(list);
@@ -804,7 +808,8 @@ AccSeqClause acc_seq_clause =
 		}
 ;
 
-//// AccGangClause:AccClause ::= [NumGangs:IntLiteralConstant] ;
+//// abstract AccExecutionModeClause:AccClause ::= [Num:IntLiteralConstant] ;
+//// AccGangClause:AccExecutionModeClause ;
 AccGangClause acc_gang_clause =
 	A_GANG LPAREN n:int_literal_constant RPAREN
 		{
@@ -816,7 +821,7 @@ AccGangClause acc_gang_clause =
 		}
 ;
 
-//// AccWorkerClause:AccClause ::= [NumWorkers:IntLiteralConstant];
+//// AccWorkerClause:AccExecutionModeClause;
 AccWorkerClause acc_worker_clause =
 
 	A_WORKER LPAREN n:int_literal_constant RPAREN
@@ -829,7 +834,7 @@ AccWorkerClause acc_worker_clause =
 		}
 ;
 
-//// AccVectorClause:AccClause ::= [VectorLength:IntLiteralConstant] ;
+//// AccVectorClause:AccExecutionModeClause ;
 AccVectorClause acc_vector_clause =
 	A_VECTOR LPAREN n:int_literal_constant RPAREN
 		{
diff --git a/Parser/spec/OpenAccRewrites.jrag b/Parser/spec/OpenAccRewrites.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..d981e84fc6f1e7b20440ecb9874eacd91cc1df9f
--- /dev/null
+++ b/Parser/spec/OpenAccRewrites.jrag
@@ -0,0 +1,105 @@
+aspect OpenAccRewrites {
+  rewrite AccParallelLoopConstruct {
+    to AccParallelConstruct {
+      List<AccClause> parallelClauses = new List<AccClause>();
+      List<AccClause> loopClauses = new List<AccClause>();
+      for (AccClause clause : getAccParallelLoopStmt().getAccClauseList()) {
+        if (clause.prefersLoop()) {
+          loopClauses.add(clause);
+        } else {
+          parallelClauses.add(clause);
+        }
+      }
+      AccLoopConstruct loop = new AccLoopConstruct(new AccLoopStmt(loopClauses), getDoConstruct(), new Opt<>(new AccEndLoopStmt()));
+      return new AccParallelConstruct(
+          new AccParallelStmt(parallelClauses),
+          new Block(new List<ExecutionPartConstruct>().add(new ExecutableConstruct_ExecutionPartConstruct(loop))),
+          new AccEndParallelStmt()
+          );
+    }
+  }
+
+  rewrite AccKernelsLoopConstruct {
+    to AccKernelsConstruct {
+      List<AccClause> kernelsClauses = new List<AccClause>();
+      List<AccClause> loopClauses = new List<AccClause>();
+      for (AccClause clause : getAccKernelsLoopStmt().getAccClauseList()) {
+        if (clause.prefersLoop()) {
+          loopClauses.add(clause);
+        } else {
+          kernelsClauses.add(clause);
+        }
+      }
+      AccLoopConstruct loop = new AccLoopConstruct(new AccLoopStmt(loopClauses), getDoConstruct(), new Opt<>(new AccEndLoopStmt()));
+      return new AccKernelsConstruct(
+          new AccKernelsStmt(kernelsClauses),
+          new Block(new List<ExecutionPartConstruct>().add(new ExecutableConstruct_ExecutionPartConstruct(loop))),
+          new AccEndKernelsStmt()
+      );
+    }
+  }
+
+  syn boolean AccClause.prefersLoop();
+  eq AccDataClause.prefersLoop() = false;
+  eq AccClause.prefersLoop() = false;
+  eq AccCollapseClause.prefersLoop() = true;
+  eq AccExecutionModeClause.prefersLoop() = true;
+  eq AccSeqClause.prefersLoop() = true;
+  eq AccAutoClause.prefersLoop() = true;
+  eq AccTileClause.prefersLoop() = true;
+  eq AccDeviceTypeClause.prefersLoop() = true;
+  eq AccIndependentClause.prefersLoop() = true;
+  eq AccPrivateClause.prefersLoop() = true;
+  eq AccReductionClause.prefersLoop() = true;
+
+  rewrite AccStmt {
+    when (containedRemovableClause() != null)
+    to AccStmt {
+      ASTNode parent = containedRemovableClause().getParent();
+      int i = parent.getIndexOfChild(containedRemovableClause());
+      if(i>-1){
+        parent.removeChild(i);
+      }
+      return this;
+    }
+  }
+
+  syn AccClause AccStmt.containedRemovableClause();
+  eq AccStmt.containedRemovableClause() = null;
+  eq AccAbstractDataStmt.containedRemovableClause() {
+    for (AccClause clause: getAccClauseList()) {
+      if (clause.canBeRemoved()) {
+        return clause;
+      }
+    }
+    return null;
+  }
+  eq AccLoopStmt.containedRemovableClause() {
+    for (AccClause clause: getAccClauseList()) {
+      if (clause.canBeRemoved()) {
+        return clause;
+      }
+    }
+    return null;
+  }
+
+  syn boolean AccClause.canBeRemoved() = false;
+  eq AccDataClause.canBeRemoved() {
+    return (getVariableList().numChildren() == 0);
+  }
+  eq AccCollapseClause.canBeRemoved() {
+    return getCount().getDigitString().getDigits().equals("1");
+  }
+
+  rewrite AccLoopStmt {
+    when (containedRemovableClause() != null)
+    to AccLoopStmt {
+    ASTNode parent = containedRemovableClause().getParent();
+      int i = parent.getIndexOfChild(containedRemovableClause());
+      if(i>-1){
+        parent.removeChild(i);
+      }
+      return this;
+    }
+  }
+}
\ No newline at end of file