diff --git a/Parser/spec/Fortran2008.rats b/Parser/spec/Fortran2008.rats
index 410beeeed6da9c7330ec061e989061edfb22d4b8..c2571b7c2bbcd1d0f3aa789ff315ef0a14d17570 100644
--- a/Parser/spec/Fortran2008.rats
+++ b/Parser/spec/Fortran2008.rats
@@ -4608,81 +4608,98 @@ EndCriticalStmt end_critical_stmt =
 //// abstract DoConstruct:ExecutableConstruct ;
 DoConstruct do_construct =
 <BEGINNING>
-    block_do_concurrent_construct
-/   block_do_while_construct
-/   block_do_construct
+    block_do_construct
 ;
 
 //// // R814
-//// BlockDoConstruct:DoConstruct ::= DoStmt DoBlock EndDo ;
+//// BlockDoConstruct:DoConstruct ::= DoBlock EndDo ;
 BlockDoConstruct block_do_construct =
-    s:do_stmt b:do_block e:end_do
+<BEGINNING>
+    do_concurrent_construct
+/   do_while_construct
+/   simple_do_construct
+/   infinite_do_construct
+;
+
+//// SimpleDoConstruct:BlockDoConstruct ::= DoStmt:SimpleDoStmt DoBlock EndDo ;
+SimpleDoConstruct simple_do_construct =
+    s:simple_do_stmt b:do_block e:end_do
         {
-            yyValue = new BlockDoConstruct(s, b, e);
+            yyValue = new SimpleDoConstruct(s, b, e);
         }
 ;
 
-//// BlockDoConcurrentConstruct:DoConstruct ::= DoStmt DoBlock EndDo ;
-BlockDoConcurrentConstruct block_do_concurrent_construct =
+//// InfiniteDoConstruct:BlockDoConstruct ::= DoStmt:InfiniteDoStmt DoBlock EndDo ;
+InfiniteDoConstruct infinite_do_construct =
+    s:infinite_do_stmt b:do_block e:end_do
+        {
+            yyValue = new InfiniteDoConstruct(s, b, e);
+        }
+;
+
+//// DoConcurrentConstruct:BlockDoConstruct ::= DoStmt:DoConcurrentStmt DoBlock EndDo ;
+DoConcurrentConstruct do_concurrent_construct =
     s:do_concurrent_stmt b:do_block e:end_do
         {
-            yyValue = new BlockDoConcurrentConstruct(s, b, e);
+            yyValue = new DoConcurrentConstruct(s, b, e);
         }
 ;
 
 
-//// BlockDoWhileConstruct:DoConstruct ::= DoStmt DoBlock EndDo ;
-BlockDoWhileConstruct block_do_while_construct =
+//// DoWhileConstruct:BlockDoConstruct ::= DoStmt:DoWhileStmt DoBlock EndDo ;
+DoWhileConstruct do_while_construct =
     s:do_while_stmt b:do_block e:end_do
         {
-            yyValue = new BlockDoWhileConstruct(s, b, e);
+            yyValue = new DoWhileConstruct(s, b, e);
         }
 ;
 
 //// // R815
-//// DoStmt:AbstractStmt ::= [DoConstructName:Name] [LoopControl];
+//// abstract DoStmt:AbstractStmt ::= [DoConstructName:Name];
 DoStmt do_stmt =
-    n:(yyValue:name COLON)? DO l:label c:(simple_loop_control)? lnc:comment
-        {
-            Opt<Name> n_opt = (n==null) ? new Opt<Name>() : new Opt<Name>(n);
-            Opt<LoopControl> c_opt = (c==null) ? new Opt<LoopControl>() : new Opt<LoopControl>(c);
-            yyValue = new DoStmt(new Opt<Label>(l), lnc, n_opt, c_opt);
-        }
-/   n:(yyValue:name COLON)? DO c:(simple_loop_control)? lnc:comment
-        {
-            Opt<Name> n_opt = (n==null) ? new Opt<Name>() : new Opt<Name>(n);
-            Opt<LoopControl> c_opt = (c==null) ? new Opt<LoopControl>() : new Opt<LoopControl>(c);
-            yyValue = new DoStmt(new Opt<Label>(), lnc, n_opt, c_opt);
-        }
+    infinite_do_stmt
+/   simple_do_stmt
+/   do_concurrent_stmt
+/   do_while_stmt
 ;
 
-DoStmt do_concurrent_stmt =
-    n:(yyValue:name COLON)? DO l:label c:concurrent_loop_control lnc:comment
+//// InfiniteDoStmt:DoStmt ;
+InfiniteDoStmt infinite_do_stmt =
+    n:(yyValue:name COLON)? DO l:label? lnc:comment
         {
             Opt<Name> n_opt = (n==null) ? new Opt<Name>() : new Opt<Name>(n);
-            Opt<LoopControl> c_opt = (c==null) ? new Opt<LoopControl>() : new Opt<LoopControl>(c);
-            yyValue = new DoStmt(new Opt<Label>(l), lnc, n_opt, c_opt);
+            Opt<Label> l_opt = (l==null) ? new Opt<Label>() : new Opt<Label>(l);
+            yyValue = new InfiniteDoStmt(l_opt, lnc, n_opt);
         }
-/   n:(yyValue:name COLON)? DO c:concurrent_loop_control lnc:comment
+;
+
+//// SimpleDoStmt:DoStmt ::=  SimpleLoopControl;
+SimpleDoStmt simple_do_stmt =
+    n:(yyValue:name COLON)? DO l:label? c:simple_loop_control lnc:comment
         {
             Opt<Name> n_opt = (n==null) ? new Opt<Name>() : new Opt<Name>(n);
-            Opt<LoopControl> c_opt = (c==null) ? new Opt<LoopControl>() : new Opt<LoopControl>(c);
-            yyValue = new DoStmt(new Opt<Label>(), lnc, n_opt, c_opt);
+            Opt<Label> l_opt = (l==null) ? new Opt<Label>() : new Opt<Label>(l);
+            yyValue = new SimpleDoStmt(l_opt, lnc, n_opt, c);
         }
 ;
 
-DoStmt do_while_stmt =
-    n:(yyValue:name COLON)? DO l:label c:while_loop_control lnc:comment
+//// DoConcurrentStmt:DoStmt ::= ConcurrentLoopControl ;
+DoConcurrentStmt do_concurrent_stmt =
+    n:(yyValue:name COLON)? DO l:label? c:concurrent_loop_control lnc:comment
         {
             Opt<Name> n_opt = (n==null) ? new Opt<Name>() : new Opt<Name>(n);
-            Opt<LoopControl> c_opt = (c==null) ? new Opt<LoopControl>() : new Opt<LoopControl>(c);
-            yyValue = new DoStmt(new Opt<Label>(l), lnc, n_opt, c_opt);
+            Opt<Label> l_opt = (l==null) ? new Opt<Label>() : new Opt<Label>(l);
+            yyValue = new DoConcurrentStmt(l_opt, lnc, n_opt, c);
         }
-/   n:(yyValue:name COLON)? DO c:while_loop_control lnc:comment
+;
+
+//// DoWhileStmt:DoStmt ::= WhileLoopControl ;
+DoWhileStmt do_while_stmt =
+    n:(yyValue:name COLON)? DO l:label? c:while_loop_control lnc:comment
         {
             Opt<Name> n_opt = (n==null) ? new Opt<Name>() : new Opt<Name>(n);
-            Opt<LoopControl> c_opt = (c==null) ? new Opt<LoopControl>() : new Opt<LoopControl>(c);
-            yyValue = new DoStmt(new Opt<Label>(), lnc, n_opt, c_opt);
+            Opt<Label> l_opt = (l==null) ? new Opt<Label>() : new Opt<Label>(l);
+            yyValue = new DoWhileStmt(l_opt, lnc, n_opt, c);
         }
 ;
 
diff --git a/Parser/spec/OpenAcc.rats b/Parser/spec/OpenAcc.rats
index e99cf13283674a61d4cb790d37e40f8978a8464d..6aac0d16958b91efb2b40f690b427cccb2275bf8 100644
--- a/Parser/spec/OpenAcc.rats
+++ b/Parser/spec/OpenAcc.rats
@@ -244,7 +244,7 @@ AccEndAtomicStmt acc_end_atomic_stmt =
 ;
 
 // loop constructs -------------------------------------------------------------
-//// abstract AccDoConstruct:DoConstruct ;
+//// abstract AccDoConstruct:DoConstruct ::= DoConstruct ;
 AccDoConstruct acc_do_construct =
     acc_loop_construct
 /   acc_parallel_loop_construct
diff --git a/Parser/spec/OpenMp.rats b/Parser/spec/OpenMp.rats
index f45019d6dbb8738c367aaa73cd0b1e7f4291a186..aee2ba24f5600bc44132d496f045f2e43c30e0c8 100644
--- a/Parser/spec/OpenMp.rats
+++ b/Parser/spec/OpenMp.rats
@@ -798,7 +798,7 @@ OmpEndOrderedStmt omp_end_ordered_stmt =
 //                              Loop Constructs
 // =============================================================================
 
-//// abstract OmpLoopConstruct:DoConstruct ;
+//// abstract OmpLoopConstruct:DoConstruct ::= DoConstruct ;
 OmpLoopConstruct omp_loop_construct =
     omp_do_construct
 /   omp_simd_construct
diff --git a/Parser/spec/Printing.jadd b/Parser/spec/Printing.jadd
index 325f92f7abcb9841007157c178353e913cdeecc5..7cd96415c1c729e3f688cd88cb35c39b6cc07199 100644
--- a/Parser/spec/Printing.jadd
+++ b/Parser/spec/Printing.jadd
@@ -2881,7 +2881,7 @@ class PrettyPrint {
     }
 
     // R814
-    public void BlockDoConstruct.prettyPrint(PrettyPrinter s) {
+    public void SimpleDoConstruct.prettyPrint(PrettyPrinter s) {
         getDoStmt().prettyPrint(s);
         s.ind();
         getDoBlock().prettyPrint(s);
@@ -2889,7 +2889,7 @@ class PrettyPrint {
         getEndDo().prettyPrint(s);
     }
 
-    public void BlockDoConcurrentConstruct.prettyPrint(PrettyPrinter s) {
+    public void InfiniteDoConstruct.prettyPrint(PrettyPrinter s) {
         getDoStmt().prettyPrint(s);
         s.ind();
         getDoBlock().prettyPrint(s);
@@ -2897,7 +2897,15 @@ class PrettyPrint {
         getEndDo().prettyPrint(s);
     }
 
-    public void BlockDoWhileConstruct.prettyPrint(PrettyPrinter s) {
+    public void DoConcurrentConstruct.prettyPrint(PrettyPrinter s) {
+        getDoStmt().prettyPrint(s);
+        s.ind();
+        getDoBlock().prettyPrint(s);
+        s.und();
+        getEndDo().prettyPrint(s);
+    }
+
+    public void DoWhileConstruct.prettyPrint(PrettyPrinter s) {
         getDoStmt().prettyPrint(s);
         s.ind();
         getDoBlock().prettyPrint(s);
@@ -2906,7 +2914,32 @@ class PrettyPrint {
     }
 
     // R815
-    public void DoStmt.prettyPrint(PrettyPrinter s) {
+    public void InfiniteDoStmt.prettyPrint(PrettyPrinter s) {
+        if (hasDoConstructName()) {
+            getDoConstructName().prettyPrint(s);
+            s.append(": ");
+        }
+        s.append("DO");
+        if (hasLabel()) {
+            s.append(" ");
+            getLabel().prettyPrint(s);
+        }
+        getComment().prettyPrint(s);
+    }
+    public void SimpleDoStmt.prettyPrint(PrettyPrinter s) {
+        if (hasDoConstructName()) {
+            getDoConstructName().prettyPrint(s);
+            s.append(": ");
+        }
+        s.append("DO ");
+        if (hasLabel()) {
+            getLabel().prettyPrint(s);
+            s.append(" ");
+        }
+        getSimpleLoopControl().prettyPrint(s);
+        getComment().prettyPrint(s);
+    }
+    public void DoConcurrentStmt.prettyPrint(PrettyPrinter s) {
         if (hasDoConstructName()) {
             getDoConstructName().prettyPrint(s);
             s.append(": ");
@@ -2916,9 +2949,20 @@ class PrettyPrint {
             getLabel().prettyPrint(s);
             s.append(" ");
         }
-        if (hasLoopControl()) {
-            getLoopControl().prettyPrint(s);
+        getConcurrentLoopControl().prettyPrint(s);
+        getComment().prettyPrint(s);
+    }
+    public void DoWhileStmt.prettyPrint(PrettyPrinter s) {
+        if (hasDoConstructName()) {
+            getDoConstructName().prettyPrint(s);
+            s.append(": ");
+        }
+        s.append("DO ");
+        if (hasLabel()) {
+            getLabel().prettyPrint(s);
+            s.append(" ");
         }
+        getWhileLoopControl().prettyPrint(s);
         getComment().prettyPrint(s);
     }