Improved grammar.
Better sema representation of OID values.
# object identifier value
name_form = Unique(identifier)
- number_form = number | defined_value
+ number_form = Unique(number)
name_and_number_form = name_form + Suppress('(') + number_form + Suppress(')')
objid_components = name_and_number_form | name_form | number_form | defined_value
objid_components_list = OneOrMore(objid_components)
module_definition.setParseAction(annotate('ModuleDefinition'))
extension_marker.setParseAction(annotate('ExtensionMarker'))
name_form.setParseAction(annotate('NameForm'))
+ number_form.setParseAction(annotate('NumberForm'))
name_and_number_form.setParseAction(annotate('NameAndNumberForm'))
object_identifier_value.setParseAction(annotate('ObjectIdentifierValue'))
ValueListType: self.expr_value_list_type,
ChoiceType: self.expr_constructed_type,
SequenceType: self.expr_constructed_type,
- SetType: self.expr_constructed_type
+ SetType: self.expr_constructed_type,
+ ObjectIdentifierValue: self.expr_object_identifier_value
}
def generate_code(self):
def decl_value_assignment(self, assignment):
assigned_value, type_decl, value = assignment.value_name, assignment.type_decl, assignment.value
+ if isinstance(value, ObjectIdentifierValue):
+ value = self.expr_object_identifier_value(value)
+
value_type = _translate_type(type_decl.type_name)
return '%s = %s(%s)' % (assigned_value, value_type, value)
+ def expr_object_identifier_value(self, t):
+ normalized_components = []
+
+ for c in t.components:
+ if isinstance(c, NameForm):
+ if c.name in REGISTERED_OID_NAMES:
+ normalized_components.append('univ.ObjectIdentifier((%s,))' % REGISTERED_OID_NAMES[c.name])
+ else:
+ # TODO: handle defined values
+ normalized_components.append('univ.ObjectIdentifier((%s,))' % c.name)
+ elif isinstance(c, NumberForm):
+ normalized_components.append('univ.ObjectIdentifier((%s,))' % c.value)
+ elif isinstance(c, NameAndNumberForm):
+ normalized_components.append('univ.ObjectIdentifier((%s,))' % c.number.value)
+ else:
+ assert False
+
+ return ' + '.join(normalized_components)
+
def generate_pyasn1(sema_module, out_stream):
return Pyasn1Backend(sema_module, out_stream).generate_code()
return sorted(assignments, key=lambda a: topological_order.index(a.reference_name()))
+# Registered object identifier names
+REGISTERED_OID_NAMES = {
+ 'ccitt': 0,
+ 'iso': 1,
+ 'joint-iso-ccitt': 2,
+ # ccitt
+ 'recommendation': 0,
+ 'question': 1,
+ 'administration': 2,
+ 'network-operator': 3,
+ # iso
+ 'standard': 0,
+ 'registration-authority': 1,
+ 'member-body': 2,
+ 'identified-organization': 3,
+ # joint-iso-ccitt
+ 'country': 16,
+ 'registration-procedures': 17
+}
+
"""
Sema nodes
refs = [self.type_decl.reference_name()]
if isinstance(self.value, ValueReference):
refs.append(self.value.reference_name())
+ elif isinstance(self.value, ObjectIdentifierValue):
+ refs.extend(self.value.references())
else:
# It's a literal, and they don't play into declaration order.
pass
__repr__ = __str__
+class NumberForm(object):
+ def __init__(self, elements):
+ self.value = elements[0]
+
+ def references(self):
+ return []
+
+ def __str__(self):
+ return str(self.value)
+
+ __repr__ = __str__
+
+
class NameAndNumberForm(object):
def __init__(self, elements):
# The first element is a NameForm containing only the
# name, so unpack it into a string.
self.name = elements[0].elements[0]
- self.number = _maybe_create_sema_node(elements[1])
+ self.number = _create_sema_node(elements[1])
def references(self):
return [str(self.name), str(self.number)]
class ObjectIdentifierValue(object):
def __init__(self, elements):
- self.components = [_maybe_create_sema_node(c) for c in elements]
+ self.components = [_create_sema_node(c) for c in elements]
def references(self):
- references = []
+ refs = []
for component in self.components:
if not isinstance(component, str):
- references.extend(component.references())
+ refs.extend(component.references())
+ else:
+ refs.append(component)
- return references
+ return refs
def __str__(self):
return '{' + ' '.join(str(x) for x in self.components) + '}'
return ObjectIdentifierValue(token.elements)
elif token.ty == 'NameForm':
return NameForm(token.elements)
+ elif token.ty == 'NumberForm':
+ return NumberForm(token.elements)
elif token.ty == 'NameAndNumberForm':
return NameAndNumberForm(token.elements)
-- Value assignment, name form
-- First three parts are known names, the last one a defined value.
local INTEGER ::= 1234
- v3 OBJECT IDENTIFIER ::= {iso member-body us local}
+ v3 OBJECT IDENTIFIER ::= {iso member-body us(840) local}
-- Value assignment, mixed
v4 OBJECT IDENTIFIER ::= {v1 723 local}