diff --git a/examples/dns.c b/examples/dns.c
index f5915912c15f33eccb8dd421ef18f49cd6664613..8afd29c83702c5a66f5dee9c30a0aee63a20b1a9 100644
--- a/examples/dns.c
+++ b/examples/dns.c
@@ -64,58 +64,52 @@ void set_rdata(struct dns_rr rr, HCountedArray *rdata) {
   // Pack the parsed rdata into rr.
   switch(rr.type) {
   case 1: // A
-    rr.a = p->ast->seq->elements[0]->uint;
+    rr.a     = p->ast->seq->elements[0]->uint;
     break;
   case 2: // NS
-    rr.ns = *(dns_domain_t *)p->ast->user;
+    rr.ns    = *(dns_domain_t *)p->ast->user;
     break;
   case 3: // MD
-    rr.md = *(dns_domain_t *)p->ast->user;
+    rr.md    = *(dns_domain_t *)p->ast->user;
     break;
   case 4: // MF
-    rr.md = *(dns_domain_t *)p->ast->user;
+    rr.md    = *(dns_domain_t *)p->ast->user;
     break;
   case 5: // CNAME
     rr.cname = *(dns_domain_t *)p->ast->user;
     break;
   case 6: // SOA
-    rr.soa = *(dns_rr_soa_t *)p->ast->user;
+    rr.soa   = *(dns_rr_soa_t *)p->ast->user;
     break;
   case 7: // MB
-    rr.mb = *(dns_domain_t *)p->ast->user;
+    rr.mb    = *(dns_domain_t *)p->ast->user;
     break;
   case 8: // MG
-    rr.mg = *(dns_domain_t *)p->ast->user;
+    rr.mg    = *(dns_domain_t *)p->ast->user;
     break;
   case 9: // MR
-    rr.mr = *(dns_domain_t *)p->ast->user;
+    rr.mr    = *(dns_domain_t *)p->ast->user;
     break;
   case 10: // NULL
-    rr.null = h_arena_malloc(rdata->arena, sizeof(uint8_t)*p->ast->seq->used);
-    for (size_t i=0; i<p->ast->seq->used; ++i)
-      rr.null[i] = p->ast->seq->elements[i]->uint;
-    // XXX Where is the length stored!?
+    rr.null  = *(dns_rr_null_t *)p->ast->user;
     break;
   case 11: // WKS
-    rr.wks = *(dns_rr_wks_t *)p->ast->user;
+    rr.wks   = *(dns_rr_wks_t *)p->ast->user;
     break;
   case 12: // PTR
-    rr.ptr = *(dns_domain_t *)p->ast->user;
+    rr.ptr   = *(dns_domain_t *)p->ast->user;
     break;
   case 13: // HINFO
-    rr.hinfo.cpu = *H_FIELD(dns_cstr_t, 0);
-    rr.hinfo.os  = *H_FIELD(dns_cstr_t, 1);
+    rr.hinfo = *(dns_rr_hinfo_t *)p->ast->user;
     break;
   case 14: // MINFO
-    rr.minfo.rmailbx = *H_FIELD(dns_domain_t, 0);
-    rr.minfo.emailbx = *H_FIELD(dns_domain_t, 1);
+    rr.minfo = *(dns_rr_minfo_t *)p->ast->user;
     break;
   case 15: // MX
-    rr.mx.preference = p->ast->seq->elements[0]->uint;
-    rr.mx.exchange = *H_FIELD(dns_domain_t, 1);
+    rr.mx    = *(dns_rr_mx_t *)p->ast->user;
     break;
   case 16: // TXT
-    rr.txt = *(dns_rr_txt_t *)p->ast->user;
+    rr.txt   = *(dns_rr_txt_t *)p->ast->user;
     break;
   default:
     break;
diff --git a/examples/dns.h b/examples/dns.h
index 2cff91633d347feff85d4ed549a9801762caaa38..ed2c26f7d5c233b5e5f6764fd635da31af90002a 100644
--- a/examples/dns.h
+++ b/examples/dns.h
@@ -13,6 +13,7 @@ enum DNSTokenType_ {
   TT_dns_rr_mx_t,
   TT_dns_rr_soa_t,
   TT_dns_rr_wks_t,
+  TT_dns_rr_null_t,
   TT_dns_domain_t,
   TT_dns_cstr_t
 };
@@ -83,6 +84,8 @@ typedef struct {
   uint8_t* bit_map;
 } dns_rr_wks_t;
 
+typedef uint8_t *dns_rr_null_t;
+
 typedef struct dns_rr {
   char* name;
   uint16_t type;
@@ -99,7 +102,7 @@ typedef struct dns_rr {
     char*          mb;
     char*          mg;
     char*          mr;
-    uint8_t*       null;
+    dns_rr_null_t  null;
     dns_rr_wks_t   wks;
     char*          ptr;
     dns_rr_hinfo_t hinfo;
diff --git a/examples/rr.c b/examples/rr.c
index 83241d84f7ff9c7e28ca3262351532abfb535a67..6bfb78217818c50a65dcf3ee36b1bafc09606ec0 100644
--- a/examples/rr.c
+++ b/examples/rr.c
@@ -6,12 +6,28 @@
 #define false 0
 #define true 1
 
+
+///
+// Validations and Semantic Actions
+///
+
 bool validate_null(HParseResult *p) {
   if (TT_SEQUENCE != p->ast->token_type)
     return false;
   return (65536 > p->ast->seq->used);
 }
 
+const HParsedToken *act_null(const HParseResult *p) {
+  dns_rr_null_t *null = H_MAKE(dns_rr_null_t);
+
+  size_t len = p->ast->seq->used;
+  uint8_t *buf = h_arena_malloc(p->arena, sizeof(uint8_t)*len);
+  for (size_t i=0; i<len; ++i)
+    buf[i] = p->ast->seq->elements[i]->uint;
+
+  return H_MAKE_TOKEN(dns_rr_null_t, null);
+}
+
 const HParsedToken *act_txt(const HParseResult *p) {
   dns_rr_txt_t *txt = H_MAKE(dns_rr_txt_t);
 
@@ -70,6 +86,38 @@ const HParsedToken* act_wks(const HParseResult *p) {
   return H_MAKE_TOKEN(dns_rr_wks_t, wks);
 }
 
+const HParsedToken* act_hinfo(const HParseResult *p) {
+  dns_rr_hinfo_t *hinfo = H_MAKE(dns_rr_hinfo_t);
+
+  hinfo->cpu = *H_FIELD(dns_cstr_t, 0);
+  hinfo->os  = *H_FIELD(dns_cstr_t, 1);
+
+  return H_MAKE_TOKEN(dns_rr_hinfo_t, hinfo);
+}
+
+const HParsedToken* act_minfo(const HParseResult *p) {
+  dns_rr_minfo_t *minfo = H_MAKE(dns_rr_minfo_t);
+
+  minfo->rmailbx = *H_FIELD(dns_domain_t, 0);
+  minfo->emailbx = *H_FIELD(dns_domain_t, 1);
+
+  return H_MAKE_TOKEN(dns_rr_minfo_t, minfo);
+}
+
+const HParsedToken* act_mx(const HParseResult *p) {
+  dns_rr_mx_t *mx = H_MAKE(dns_rr_mx_t);
+
+  mx->preference = p->ast->seq->elements[0]->uint;
+  mx->exchange   = *H_FIELD(dns_domain_t, 1);
+
+  return H_MAKE_TOKEN(dns_rr_mx_t, mx);
+}
+
+
+///
+// Parsers for all types of RDATA
+///
+
 #define RDATA_TYPE_MAX 16
 const HParser* init_rdata(uint16_t type) {
   static const HParser *parsers[RDATA_TYPE_MAX+1];