parser: tag data members

It's cleaner to differentiate between the different types of member AST by
using the first element as a tag.
diff --git a/loxi_front_end/frontend.py b/loxi_front_end/frontend.py
index 209b31c..256ae70 100644
--- a/loxi_front_end/frontend.py
+++ b/loxi_front_end/frontend.py
@@ -37,13 +37,14 @@
 def create_member(m_ast):
     if m_ast[0] == 'pad':
         return OFPadMember(length=m_ast[1])
-    elif m_ast[1] == 'length' or m_ast[1] == 'len': # Should be moved to parser
-        return OFLengthMember(name=m_ast[1], oftype=m_ast[0])
-    elif m_ast[1] == 'actions_len':
-        # HACK only usage so far
-        return OFFieldLengthMember(name=m_ast[1], oftype=m_ast[0], field_name='actions')
-    else:
-        return OFDataMember(name=m_ast[1], oftype=m_ast[0])
+    elif m_ast[0] == 'data':
+        if m_ast[2] == 'length' or m_ast[2] == 'len': # Should be moved to parser
+            return OFLengthMember(name=m_ast[2], oftype=m_ast[1])
+        elif m_ast[2] == 'actions_len':
+            # HACK only usage so far
+            return OFFieldLengthMember(name=m_ast[2], oftype=m_ast[1], field_name='actions')
+        else:
+            return OFDataMember(name=m_ast[2], oftype=m_ast[1])
 
 def create_ofinput(ast):
     """
diff --git a/loxi_front_end/parser.py b/loxi_front_end/parser.py
index 5e994dc..ab6bfc4 100644
--- a/loxi_front_end/parser.py
+++ b/loxi_front_end/parser.py
@@ -51,7 +51,8 @@
 
 # Structs
 pad_member = P.Group(kw('pad') - s('(') - integer - s(')'))
-struct_member = pad_member | P.Group(any_type - identifier);
+data_member = P.Group(tag('data') + any_type - identifier)
+struct_member = pad_member | data_member;
 struct = kw('struct') - identifier - s('{') + \
          P.Group(P.ZeroOrMore(struct_member - s(';'))) + \
          s('}') - s(';')
diff --git a/utest/test_frontend.py b/utest/test_frontend.py
index 7af5121..2119363 100755
--- a/utest/test_frontend.py
+++ b/utest/test_frontend.py
@@ -85,20 +85,20 @@
                 ['OFPPC_NO_PACKET_IN', 64]]],
             ['metadata', 'version', '2'],
             ['struct', 'of_echo_reply', [
-                ['uint8_t', 'version'],
-                ['uint8_t', 'type'],
-                ['uint16_t', 'length'],
-                ['uint32_t', 'xid'],
-                ['of_octets_t', 'data']]],
+                ['data', 'uint8_t', 'version'],
+                ['data', 'uint8_t', 'type'],
+                ['data', 'uint16_t', 'length'],
+                ['data', 'uint32_t', 'xid'],
+                ['data', 'of_octets_t', 'data']]],
             ['enum', 'ofp_queue_op_failed_code', [
                 ['OFPQOFC_BAD_PORT', 0],
                 ['OFPQOFC_BAD_QUEUE', 1],
                 ['OFPQOFC_EPERM', 2]]],
             ['struct', 'of_packet_queue', [
-                ['uint32_t', 'queue_id'],
-                ['uint16_t', 'len'],
+                ['data', 'uint32_t', 'queue_id'],
+                ['data', 'uint16_t', 'len'],
                 ['pad', 2],
-                ['list(of_queue_prop_t)', 'properties']]],
+                ['data', 'list(of_queue_prop_t)', 'properties']]],
         ]
         self.assertEquals(expected_ast, ast)
 
diff --git a/utest/test_parser.py b/utest/test_parser.py
index da262a4..a4a0e63 100755
--- a/utest/test_parser.py
+++ b/utest/test_parser.py
@@ -46,7 +46,7 @@
 """
         ast = parser.parse(src)
         self.assertEquals(ast,
-            [['struct', 'foo', [['uint32_t', 'bar']]]])
+            [['struct', 'foo', [['data', 'uint32_t', 'bar']]]])
 
     def test_multiple_fields(self):
         src = """\
@@ -59,9 +59,9 @@
         ast = parser.parse(src)
         self.assertEquals(ast,
             [['struct', 'foo',
-                [['uint32_t', 'bar'],
-                 ['uint8_t', 'baz'],
-                 ['uint64_t', 'abc']]]])
+                [['data', 'uint32_t', 'bar'],
+                 ['data', 'uint8_t', 'baz'],
+                 ['data', 'uint64_t', 'abc']]]])
 
     def test_array_type(self):
         src = """\
@@ -71,7 +71,7 @@
 """
         ast = parser.parse(src)
         self.assertEquals(ast,
-            [['struct', 'foo', [['uint32_t[4]', 'bar']]]])
+            [['struct', 'foo', [['data', 'uint32_t[4]', 'bar']]]])
 
     def test_list_type(self):
         src = """\
@@ -81,7 +81,7 @@
 """
         ast = parser.parse(src)
         self.assertEquals(ast,
-            [['struct', 'foo', [['list(of_action_t)', 'bar']]]])
+            [['struct', 'foo', [['data', 'list(of_action_t)', 'bar']]]])
 
     def test_pad_type(self):
         src = """\
@@ -163,7 +163,7 @@
 """
         ast = parser.parse(src)
         self.assertEquals(ast,
-            [['struct', 'foo', [['uint32_t', 'a']]]])
+            [['struct', 'foo', [['data', 'uint32_t', 'a']]]])
 
     def test_mixed(self):
         src = """\