diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd
index cde27fe6206c11bdd9f562df733de2443874b48d..f5d69d3facd57a19d3d5630d339455b928ddcc68 100644
--- a/src/main/jastadd/Backend.jadd
+++ b/src/main/jastadd/Backend.jadd
@@ -100,6 +100,12 @@ aspect BackendAbstractGrammar {
   public String NTAComponent.generateAbstractGrammar() {
     return "/" + super.generateAbstractGrammar() + "/";
   }
+  public String NTAListComponent.generateAbstractGrammar() {
+    return "/" + super.generateAbstractGrammar() + "*/";
+  }
+  public String NTAOptComponent.generateAbstractGrammar() {
+    return "/[" + super.generateAbstractGrammar() + "]/";
+  }
   public String TokenComponent.generateAbstractGrammar() {
     return "<" + getID() + ":" + getTypeUse() + ">";
   }
@@ -1170,6 +1176,14 @@ aspect Serializer {
     // do not serialize NTA
   }
 
+  public void NTAListComponent.serialize(StringBuilder sb, int indent) {
+    // do not serialize NTA
+  }
+
+  public void NTAOptComponent.serialize(StringBuilder sb, int indent) {
+    // do not serialize NTA
+  }
+
   public void ListComponent.serialize(StringBuilder sb, int indent) {
     sb.append(ind(indent) + "if (getNum" + getID() + "() > 0) {\n");
     sb.append(ind(indent + 1) + "g.writeArrayFieldStart(\"" + getID() + "\");\n");
@@ -1410,6 +1424,14 @@ aspect Serializer {
     // do not serialize NTA
   }
 
+  public void NTAListComponent.deserialize(StringBuilder sb, int indent) {
+    // do not serialize NTA
+  }
+
+  public void NTAOptComponent.deserialize(StringBuilder sb, int indent) {
+    // do not serialize NTA
+  }
+
   public void ListComponent.deserialize(StringBuilder sb, int indent) {
     sb.append(ind(indent) + "for (" + jsonNodeType + " child : children.get(\"" + getID() + "\")) {\n");
     sb.append(ind(indent + 1) + "element.add" + getID() + "(" + getTypeUse().decl().getID() + ".deserialize(child));\n");
diff --git a/src/main/jastadd/RelAst.ast b/src/main/jastadd/RelAst.ast
index 9b29df1e866d7b2d4cb87e414aa16f9a3fa5feeb..f0132fc4b3a4c32f1e2f49aad19382dc64379dcf 100644
--- a/src/main/jastadd/RelAst.ast
+++ b/src/main/jastadd/RelAst.ast
@@ -8,6 +8,8 @@ NormalComponent : SimpleTypeComponent;
 ListComponent : SimpleTypeComponent;
 OptComponent : SimpleTypeComponent;
 NTAComponent : SimpleTypeComponent;
+NTAOptComponent : SimpleTypeComponent;
+NTAListComponent : SimpleTypeComponent;
 TokenComponent : Component ::= TypeUse;
 
 abstract TypeUse ::= <ID>;
diff --git a/src/main/jastadd/RelAst.parser b/src/main/jastadd/RelAst.parser
index 0a097391b2519dd89a44746e0ae092cbfb6af0c0..303dcb6dd727df10b4037d110e234213fdc90b36 100644
--- a/src/main/jastadd/RelAst.parser
+++ b/src/main/jastadd/RelAst.parser
@@ -63,8 +63,14 @@ Component component =
   | ID COL s_type_use.u STAR                  {: return new ListComponent(ID, u); :}
   | s_type_use.u STAR                         {: return new ListComponent(u.getID(), u); :}
   // Opt
-  | LBRACKET ID COL s_type_use.u RBRACKET     {: return new OptComponent(ID, u); :}
-  | LBRACKET s_type_use.u RBRACKET            {: return new OptComponent(u.getID(), u); :}
+  | LBRACKET ID COL s_type_use.u RBRACKET {: return new OptComponent(ID, u); :}
+  | LBRACKET s_type_use.u RBRACKET {: return new OptComponent(u.getID(), u); :}
+  // NTA list
+  | SLASH ID COL s_type_use.u STAR SLASH {: return new NTAListComponent(ID, u); :}
+  | SLASH s_type_use.u STAR SLASH {: return new NTAListComponent(u.getID(), u); :}
+  // NTA opt
+  | SLASH LBRACKET ID COL s_type_use.u RBRACKET SLASH {: return new NTAOptComponent(ID, u); :}
+  | SLASH LBRACKET s_type_use.u RBRACKET SLASH {: return new NTAOptComponent(u.getID(), u); :}
   // NTA
   | SLASH ID COL s_type_use.u SLASH           {: return new NTAComponent(ID, u); :}
   | SLASH s_type_use.u SLASH                  {: return new NTAComponent(u.getID(), u); :}