Parser and sema support for SIZE constraints on SEQUENCE OF.
authorKim Grasman <kim.grasman@gmail.com>
Mon, 29 Jul 2013 15:34:27 +0000 (17:34 +0200)
committerKim Grasman <kim.grasman@gmail.com>
Mon, 29 Jul 2013 15:34:27 +0000 (17:34 +0200)
asn1ate/parser.py
asn1ate/sema.py
testdata/sequenceof.asn [new file with mode: 0644]

index 3cd54a4..41a05ae 100644 (file)
@@ -224,7 +224,7 @@ def _build_asn1_grammar():
 
     set_type = SET + braced_list(component_type | extension_marker)
     sequence_type = SEQUENCE + braced_list(component_type | extension_marker)
-    sequenceof_type = SEQUENCE + Optional(optional_paren_l + size_constraint + optional_paren_r) + OF + (type_ | named_type)
+    sequenceof_type = Suppress(SEQUENCE) + Optional(optional_paren_l + size_constraint + optional_paren_r) + Suppress(OF) + (type_ | named_type)
     setof_type = Suppress(SET) + Optional(optional_paren_l + size_constraint + optional_paren_r) + Suppress(OF) + (type_ | named_type)
     choice_type = CHOICE + braced_list(named_type | extension_marker)
     enumerated_type = ENUMERATED + braced_list(enumeration)
index 73b7073..fdc55c2 100644 (file)
@@ -213,6 +213,7 @@ class ValueReference(object):
 
 
 class ConstructedType(object):
+    """ Base type for SEQUENCE, SET and CHOICE. """
     def __init__(self, elements):
         type_name, component_tokens = elements
         self.type_name = type_name
@@ -245,26 +246,11 @@ class SetType(ConstructedType):
     def __init__(self, elements):
         super(SetType, self).__init__(elements)
 
-
-class SequenceOfType(object):
-    def __init__(self, elements):
-        # TODO: handle optional size constraint
-        type_name, of_keyword, type_token = elements
-        self.type_name = type_name
-        self.type_decl = _create_sema_node(type_token)
-
-    def references(self):
-        return self.type_decl.references()
-
-    def __str__(self):
-        return '%s %s' % (self.type_name, self.type_decl)
-
-    __repr__ = __str__
-
-
-class SetOfType(object):
-    def __init__(self, elements):
-        self.type_name = 'SET OF'
+class CollectionType(object):
+    """ Base type for SET OF and SEQUENCE OF. """
+    def __init__(self, kind, elements):
+        self.kind = kind
+        self.type_name = self.kind + ' OF'
 
         if elements[0].ty == 'Type':
             self.size_constraint = None
@@ -273,22 +259,28 @@ class SetOfType(object):
             self.size_constraint = _create_sema_node(elements[0])
             self.type_decl = _create_sema_node(elements[1])
         else:
-            assert False, 'Unknown form of SET OF declaration: %s' % elements
+            assert False, 'Unknown form of %s OF declaration: %s' % (self.kind, elements)
 
     def references(self):
         return self.type_decl.references()
 
     def __str__(self):
-        result = 'SET'
-
         if self.size_constraint:
-            result += ' %s' % self.size_constraint
+            return '%s %s OF %s' % (self.kind, self.size_constraint, self.type_decl)
+        else:
+            return '%s OF %s' % (self.kind, self.type_decl)
 
-        result += ' OF %s' % self.type_decl
+    __repr__ = __str__
 
-        return result
 
-    __repr__ = __str__
+class SequenceOfType(CollectionType):
+    def __init__(self, elements):
+        super(SequenceOfType, self).__init__('SEQUENCE', elements)
+
+
+class SetOfType(CollectionType):
+    def __init__(self, elements):
+        super(SetOfType, self).__init__('SET', elements)
 
 
 class TaggedType(object):
diff --git a/testdata/sequenceof.asn b/testdata/sequenceof.asn
new file mode 100644 (file)
index 0000000..f6e50c5
--- /dev/null
@@ -0,0 +1,16 @@
+Test DEFINITIONS ::=
+BEGIN
+  -- Top-level
+  Foo ::= SEQUENCE OF INTEGER
+
+  -- Inline
+  Bar ::= SEQUENCE
+  {
+    baz SEQUENCE OF INTEGER,  -- built-in type
+    quux SEQUENCE OF Foo      -- user-defined type
+  }
+
+  -- With size constraint
+  Sized ::= SEQUENCE SIZE(1..100) OF INTEGER
+  SizedWithParens ::= SEQUENCE (SIZE(1..100)) OF INTEGER
+END