diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 88a3df2d535537d5dfbaca10a858738c47ad854a..636a054e03d19deb714cf2266bc991c4ddfbd06e 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -1776,4 +1776,13 @@
 // Enable Marlin dev mode which adds some special commands
 //#define MARLIN_DEV_MODE
 
+
+/**
+ * CNC Parsing options
+ * 
+ * These options increase marlin's acceptance of non reprap dialects more in line with what laser cutter or drawing machine cams produce
+ */
+//#define PARENTHESE_COMMENTS // Enable Marlin to interpret parenthese delimited comments as such and ignore them
+//#define STICKY_MOVE_MODE    // Enable marlin to keep the current move mode (G0 G1 G2 G3 G5 G38.X) and use it even if receiving only parameters (X Y Z E F etc.)
+
 #endif // CONFIGURATION_ADV_H
diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp
index 392532646ce5f5a650c6ee7cbd13c2e0b32360e3..0c51318600f9b8c1b6e4737a2f7b4fd9481f2f5d 100644
--- a/Marlin/src/gcode/parser.cpp
+++ b/Marlin/src/gcode/parser.cpp
@@ -53,6 +53,13 @@ int GCodeParser::codenum;
 #if USE_GCODE_SUBCODES
   uint8_t GCodeParser::subcode;
 #endif
+#if ENABLED(STICKY_MOVE_MODE)
+  int GCodeParser::current_motion_mode_codenum;	
+  #if USE_GCODE_SUBCODES		  
+    uint8_t GCodeParser::current_motion_mode_subcode;	
+  #endif
+#endif
+  
 
 #if ENABLED(FASTER_GCODE_PARSER)
   // Optimized Parameters
@@ -118,36 +125,81 @@ void GCodeParser::parse(char *p) {
   }
 
   // Bail if the letter is not G, M, or T
-  switch (letter) { case 'G': case 'M': case 'T': break; default: return; }
-
-  // Skip spaces to get the numeric part
-  while (*p == ' ') p++;
-
-  // Bail if there's no command code number
-  if (!NUMERIC(*p)) return;
-
-  // Save the command letter at this point
-  // A '?' signifies an unknown command
-  command_letter = letter;
+  switch(letter) { 
+  case 'G': 
+  case 'M': 
+  case 'T': 
+ 
+      // Skip spaces to get the numeric part
+      while (*p == ' ') p++;
+
+      // Bail if there's no command code number
+      if (!NUMERIC(*p)) return;
+
+      // Save the command letter at this point
+      // A '?' signifies an unknown command
+      command_letter = letter;
+
+      // Get the code number - integer digits only
+      codenum = 0;
+      do {
+      codenum *= 10, codenum += *p++ - '0';
+      } while (NUMERIC(*p));
+
+      // Allow for decimal point in command
+      #if USE_GCODE_SUBCODES
+      if (*p == '.') {
+        p++;
+        while (NUMERIC(*p))
+        subcode *= 10, subcode += *p++ - '0';
+      }
+      #endif
 
-  // Get the code number - integer digits only
-  codenum = 0;
-  do {
-    codenum *= 10, codenum += *p++ - '0';
-  } while (NUMERIC(*p));
+      // Skip all spaces to get to the first argument, or nul
+      while (*p == ' ') p++;
 
-  // Allow for decimal point in command
-  #if USE_GCODE_SUBCODES
-    if (*p == '.') {
-      p++;
-      while (NUMERIC(*p))
-        subcode *= 10, subcode += *p++ - '0';
-    }
-  #endif
+      #if ENABLED(STICKY_MOVE_MODE)
+        if( letter == 'G' && (codenum < 4 || codenum == 5 || codenum == 38 || (codenum>=80 &&codenum < 90  ))) {
+        current_motion_mode_codenum = codenum;
+        #if USE_GCODE_SUBCODES
+          current_motion_mode_subcode = subcode;
+        #endif
+        }
+      #endif
+      break;
+    
+  #if ENABLED(STICKY_MOVE_MODE)
+
+    case 'P':
+    case 'Q':
+      if (current_motion_mode_codenum != 5)
+        return;
+    case 'I':
+    case 'J':
+    case 'R':  
+      if (current_motion_mode_codenum < 2)
+        return;
+    case 'X':
+    case 'Y':
+    case 'Z':
+    case 'E':
+    case 'F':
+
+      command_letter = 'G';
+      codenum = current_motion_mode_codenum;
+      #if USE_GCODE_SUBCODES
+        subcode = current_motion_mode_subcode;
+      #endif
+      
+      // Roll back one character before to use the current arg
+      p--;
+    break;
+  #endif // STICKY_MOVE_MODE
 
-  // Skip all spaces to get to the first argument, or nul
-  while (*p == ' ') p++;
+  default: return; 
+  }
 
+ 
   // The command parameters (if any) start here, for sure!
 
   #if DISABLED(FASTER_GCODE_PARSER)
diff --git a/Marlin/src/gcode/parser.h b/Marlin/src/gcode/parser.h
index eb67bf14a7e197a5df7e4d849126348dfbfe3ecb..5939ea8a77725f2ffd72ea8823472199bdc55480 100644
--- a/Marlin/src/gcode/parser.h
+++ b/Marlin/src/gcode/parser.h
@@ -78,12 +78,21 @@ public:
   static char *command_ptr,               // The command, so it can be echoed
               *string_arg;                // string of command line
 
+
+
   static char command_letter;             // G, M, or T
   static int codenum;                     // 123
   #if USE_GCODE_SUBCODES
     static uint8_t subcode;               // .1
   #endif
 
+  #if ENABLED(STICKY_MOVE_MODE)
+    static int current_motion_mode_codenum;	
+    #if USE_GCODE_SUBCODES		  
+      static uint8_t current_motion_mode_subcode;	
+    #endif
+  #endif
+  
   #if ENABLED(DEBUG_GCODE_PARSER)
     static void debug();
   #endif
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 8e302488530f7bd85cb1f29abb877d832df42f47..6cbd0cc331eacd5dfb20ad6cfde7aa53ba1c52e3 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -283,6 +283,9 @@ static int read_serial(const int index) {
 inline void get_serial_commands() {
   static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE];
   static bool serial_comment_mode[NUM_SERIAL] = { false };
+  #if ENABLED(PARENTHESE_COMMENTS)
+    static bool serial_comment_paranthese_mode[NUM_SERIAL] = { false };
+  #endif
 
   // If the command buffer is empty for too long,
   // send "wait" to indicate Marlin is still waiting.
@@ -311,6 +314,9 @@ inline void get_serial_commands() {
       if (serial_char == '\n' || serial_char == '\r') {
 
         serial_comment_mode[i] = false;                   // end of line == end of comment
+        #if ENABLED(PARENTHESE_COMMENTS)
+          serial_comment_paranthese_mode[i] = false;                   // end of line == end of comment
+        #endif
 
         // Skip empty lines and comments
         if (!serial_count[i]) { thermalManager.manage_heater(); continue; }
@@ -404,12 +410,24 @@ inline void get_serial_commands() {
       }
       else if (serial_char == '\\') {  // Handle escapes
         // if we have one more character, copy it over
-        if ((c = read_serial(i)) >= 0 && !serial_comment_mode[i])
+        if ((c = read_serial(i)) >= 0 && !serial_comment_mode[i]
+        #if ENABLED(PARENTHESE_COMMENTS)
+         && ! serial_comment_paranthese_mode[i]
+        #endif
+         )
           serial_line_buffer[i][serial_count[i]++] = (char)c;
       }
       else { // it's not a newline, carriage return or escape char
-        if (serial_char == ';') serial_comment_mode[i] = true;
-        if (!serial_comment_mode[i]) serial_line_buffer[i][serial_count[i]++] = serial_char;
+        if (serial_char == ';') serial_comment_mode[i] = true; 
+        #if ENABLED(PARENTHESE_COMMENTS)
+          else if (serial_char == '(') serial_comment_paranthese_mode[i] = true;
+          else if (serial_char == ')') serial_comment_paranthese_mode[i] = false;
+        #endif
+        else if (!serial_comment_mode[i] 
+        #if ENABLED(PARENTHESE_COMMENTS)
+          && ! serial_comment_paranthese_mode[i]
+        #endif
+        ) serial_line_buffer[i][serial_count[i]++] = serial_char;
       }
     } // for NUM_SERIAL
   } // queue has space, serial has data
@@ -426,6 +444,9 @@ inline void get_serial_commands() {
     static bool stop_buffering = false,
                 sd_comment_mode = false;
 
+    #if ENABLED(PARENTHESE_COMMENTS)
+      static bool sd_comment_parenthese_mode = false;
+    #endif
     if (!IS_SD_PRINTING) return;
 
     /**
@@ -445,7 +466,11 @@ inline void get_serial_commands() {
       card_eof = card.eof();
       if (card_eof || n == -1
           || sd_char == '\n' || sd_char == '\r'
-          || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode)
+          || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode
+          #if ENABLED(PARENTHESE_COMMENTS)
+            && ! sd_comment_parenthese_mode
+          #endif
+          )
       ) {
         if (card_eof) {
 
@@ -481,6 +506,9 @@ inline void get_serial_commands() {
         if (sd_char == '#') stop_buffering = true;
 
         sd_comment_mode = false; // for new command
+        #if ENABLED(PARENTHESE_COMMENTS)
+          sd_comment_parenthese_mode = false;
+        #endif
 
         // Skip empty lines and comments
         if (!sd_count) { thermalManager.manage_heater(); continue; }
@@ -497,8 +525,17 @@ inline void get_serial_commands() {
          */
       }
       else {
-        if (sd_char == ';') sd_comment_mode = true;
-        if (!sd_comment_mode) command_queue[cmd_queue_index_w][sd_count++] = sd_char;
+        if (sd_char == ';') sd_comment_mode = true; 
+        #if ENABLED(PARENTHESE_COMMENTS)
+          else if (sd_char == '(') sd_comment_parenthese_mode = true; 
+          else if (sd_char == ')') sd_comment_parenthese_mode = false; 
+        #endif
+        else if (!sd_comment_mode
+        #if ENABLED(PARENTHESE_COMMENTS) 
+        && ! sd_comment_parenthese_mode
+        #endif
+        ) 
+          command_queue[cmd_queue_index_w][sd_count++] = sd_char;
       }
     }
   }