Sema support for SIZE constraints.
authorKim Grasman <kim.grasman@gmail.com>
Mon, 29 Jul 2013 15:16:40 +0000 (17:16 +0200)
committerKim Grasman <kim.grasman@gmail.com>
Mon, 29 Jul 2013 15:16:40 +0000 (17:16 +0200)
asn1ate/parser.py
asn1ate/sema.py
testdata/setof.asn

index 4eb3f12..3cd54a4 100644 (file)
@@ -203,7 +203,7 @@ def _build_asn1_grammar():
     value_range_min = (signed_number | valuereference | MIN)
     value_range_max = (signed_number | valuereference | MAX)
     value_range_constraint = value_range_min + Suppress('..') + value_range_max
-    size_constraint = SIZE + Suppress('(') + value_range_constraint + Suppress(')')
+    size_constraint = Suppress(SIZE) + Suppress('(') + value_range_constraint + Suppress(')')
     constraint = Suppress('(') + value_range_constraint + Suppress(')')
     optional_paren_l = Optional(Suppress('('))
     optional_paren_r = Optional(Suppress(')'))
@@ -225,7 +225,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)
-    setof_type = SET + Optional(optional_paren_l + size_constraint + optional_paren_r) + 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)
     bitstring_type = BIT_STRING + braced_list(named_number)
@@ -290,6 +290,7 @@ def _build_asn1_grammar():
     setof_type.setParseAction(annotate('SetOfType'))
     named_number.setParseAction(annotate('NamedValue'))
     constraint.setParseAction(annotate('Constraint'))
+    size_constraint.setParseAction(annotate('SizeConstraint'))
     component_type.setParseAction(annotate('ComponentType'))
     component_type_optional.setParseAction(annotate('ComponentTypeOptional'))
     component_type_default.setParseAction(annotate('ComponentTypeDefault'))
index 4f44f4e..73b7073 100644 (file)
@@ -264,16 +264,29 @@ class SequenceOfType(object):
 
 class SetOfType(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)
+        self.type_name = 'SET OF'
+
+        if elements[0].ty == 'Type':
+            self.size_constraint = None
+            self.type_decl = _create_sema_node(elements[0])
+        elif elements[0].ty == 'SizeConstraint':
+            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
 
     def references(self):
         return self.type_decl.references()
 
     def __str__(self):
-        return '%s %s' % (self.type_name, self.type_decl)
+        result = 'SET'
+
+        if self.size_constraint:
+            result += ' %s' % self.size_constraint
+
+        result += ' OF %s' % self.type_decl
+
+        return result
 
     __repr__ = __str__
 
@@ -390,6 +403,14 @@ class Constraint(object):
     __repr__ = __str__
 
 
+class SizeConstraint(Constraint):
+    """ Size constraints have the same form as any value range constraints."""
+    def __str__(self):
+        return 'SIZE(%s..%s)' % (self.min_value, self.max_value)
+
+    __repr__ = __str__
+
+
 class ComponentType(object):
     def __init__(self, elements):
         self.identifier = None
@@ -590,6 +611,8 @@ def _create_sema_node(token):
         return SetOfType(token.elements)
     elif token.ty == 'ExtensionMarker':
         return ExtensionMarker(token.elements)
+    elif token.ty == 'SizeConstraint':
+        return SizeConstraint(token.elements)
 
     raise Exception('Unknown token type: %s' % token.ty)
 
index c108a92..c6f706e 100644 (file)
@@ -6,7 +6,11 @@ BEGIN
   -- Inline\r
   Bar ::= SEQUENCE\r
   {\r
-       baz SET OF INTEGER,     -- built-in type\r
-       quux SET OF Foo         -- user-defined type\r
+    baz SET OF INTEGER,  -- built-in type\r
+    quux SET OF Foo     -- user-defined type\r
   }\r
+\r
+  -- With size constraint\r
+  Sized ::= SET SIZE(1..100) OF INTEGER\r
+  SizedWithParens ::= SET (SIZE(1..100)) OF INTEGER\r
 END\r