# todo: consider other defined types from 13.1
external_type_reference = module_reference + Suppress('.') + typereference
defined_type = external_type_reference | typereference
- referenced_type = Unique(defined_type) # todo: consider other ref:d types from 16.3
# values
sequenceof_type = Suppress(SEQUENCE) + Optional(size_constraint, default=None) + Suppress(OF) + (type_ | named_type)
setof_type = Suppress(SET) + Optional(size_constraint, default=None) + Suppress(OF) + (type_ | named_type)
choice_type = CHOICE + braced_list(named_type | extension_marker)
+ selection_type = identifier + Suppress('<') + type_
enumerated_type = ENUMERATED + braced_list(enumeration | extension_marker)
bitstring_type = BIT_STRING + Optional(braced_list(named_number), default=[]) + Optional(single_value_constraint | size_constraint, default=None)
plain_integer_type = INTEGER
value_list_type = restricted_integer_type | enumerated_type
builtin_type = value_list_type | tagged_type | simple_type | constructed_type | sequenceof_type | setof_type | bitstring_type
+ referenced_type = defined_type | selection_type # todo: consider other ref:d types from 16.3
+
type_ << (builtin_type | referenced_type)
# EXT: identifier should not be Optional here, but
assignment_list.setParseAction(annotate('AssignmentList'))
bstring.setParseAction(annotate('BinaryStringValue'))
hstring.setParseAction(annotate('HexStringValue'))
- referenced_type.setParseAction(annotate('ReferencedType'))
+ defined_type.setParseAction(annotate('DefinedType'))
+ selection_type.setParseAction(annotate('SelectionType'))
referenced_value.setParseAction(annotate('ReferencedValue'))
start = OneOrMore(module_definition)
SequenceOfType: self.defn_collection_type,
SetOfType: self.defn_collection_type,
TaggedType: self.defn_tagged_type,
+ SelectionType: self.defn_selection_type,
SimpleType: self.defn_simple_type,
- ReferencedType: self.defn_referenced_type,
+ DefinedType: self.defn_defined_type,
ValueListType: self.defn_value_list_type,
BitStringType: self.defn_bitstring_type,
}
self.inline_generators = {
TaggedType: self.inline_tagged_type,
+ SelectionType: self.inline_selection_type,
SimpleType: self.inline_simple_type,
- ReferencedType: self.inline_referenced_type,
+ DefinedType: self.inline_defined_type,
ComponentType: self.inline_component_type,
NamedType: self.inline_named_type,
SequenceOfType: self.inline_sequenceof_type,
assigned_type, type_decl = assignment.type_name, assignment.type_decl
+ if isinstance(type_decl, SelectionType):
+ type_decl = self.sema_module.resolve_selection_type(type_decl)
+
assigned_type = _translate_type(assigned_type)
base_type = _translate_type(type_decl.type_name)
fragment.write_line('class %s(%s):' % (assigned_type, base_type))
return None
- def defn_referenced_type(self, class_name, t):
+ def defn_defined_type(self, class_name, t):
return None
def defn_constructed_type(self, class_name, t):
return str(fragment)
+ def defn_selection_type(self, class_name, t):
+ return None
+
def defn_value_list_type(self, class_name, t):
fragment = self.writer.get_fragment()
return type_expr
- def inline_referenced_type(self, t):
+ def inline_defined_type(self, t):
return _translate_type(t.type_name) + '()'
def inline_constructed_type(self, t):
return type_expr
+ def inline_selection_type(self, t):
+ selected_type = self.sema_module.resolve_selection_type(t)
+ assert selected_type is not None, "Found no member %s in %s" % (t.identifier, t.type_decl)
+
+ return self.generate_expr(selected_type)
+
def build_tag_expr(self, tag_def):
context = _translate_tag_class(tag_def.class_name)
else:
return type_decl
+ def get_type_decl(self, type_name):
+ user_types = self.user_types()
+ return user_types[type_name]
+
+ def resolve_selection_type(self, selection_type_decl):
+ assert isinstance(selection_type_decl, SelectionType), "Expected SelectionType, was %s" % type(selection_type_decl).__name__
+
+ choice_type = self.get_type_decl(selection_type_decl.type_decl.type_name)
+ for named_type in choice_type.components:
+ if named_type.identifier == selection_type_decl.identifier:
+ return named_type.type_decl
+
+ return None
def __str__(self):
return '%s DEFINITIONS ::=\n' % self.name \
class ReferencedType(SemaNode):
+ pass
+
+
+class DefinedType(ReferencedType):
def __init__(self, elements):
# TODO: Module references are not resolved at the moment,
# and I'm not sure how to handle them.
__repr__ = __str__
+class SelectionType(ReferencedType):
+ def __init__(self, elements):
+ self.identifier = elements[0].elements[0]
+ self.type_decl = _create_sema_node(elements[1])
+
+ @property
+ def type_name(self):
+ return self.type_decl.type_name
+
+ def reference_name(self):
+ return self.type_name
+
+ def __str__(self):
+ return '%s < %s' % (self.identifier, self.type_name)
+
+ __repr__ = __str__
+
+
class ReferencedValue(SemaNode):
def __init__(self, elements):
# TODO: Module references are not resolved at the moment,
return _create_sema_node(token.elements[0])
elif token.ty == 'SimpleType':
return SimpleType(token.elements)
- elif token.ty == 'ReferencedType':
- return ReferencedType(token.elements)
+ elif token.ty == 'DefinedType':
+ return DefinedType(token.elements)
+ elif token.ty == 'SelectionType':
+ return SelectionType(token.elements)
elif token.ty == 'ReferencedValue':
return ReferencedValue(token.elements)
elif token.ty == 'TaggedType':
-- Collection types
SequenceOf ::= SEQUENCE OF INTEGER
SetOf ::= SET OF INTEGER
+
+ -- Selection type
+ Selection ::= a < Choice
+ SelectedSequence ::= SEQUENCE {
+ a a < Choice,
+ b b < Choice
+ }
END