Rudimentary support for imports. Ignored in sema.
authorKim Grasman <kim.grasman@gmail.com>
Sun, 25 Aug 2013 14:00:34 +0000 (16:00 +0200)
committerKim Grasman <kim.grasman@gmail.com>
Sun, 25 Aug 2013 14:00:34 +0000 (16:00 +0200)
asn1ate/parser.py
asn1ate/sema.py
testdata/imports.asn [new file with mode: 0644]

index fd13169..8bbb7ae 100644 (file)
@@ -117,6 +117,8 @@ def _build_asn1_grammar():
     ELLIPSIS = Keyword('...')
     SIZE = Keyword('SIZE')
     OF = Keyword('OF')
+    IMPORTS = Keyword('IMPORTS')
+    FROM = Keyword('FROM')
 
     # Built-in types
     SEQUENCE = Keyword('SEQUENCE')
@@ -165,6 +167,7 @@ def _build_asn1_grammar():
     valuereference = build_identifier('[a-z]')
     typereference = build_identifier('[A-Z]')
     module_reference = build_identifier('[A-Z]')
+    reference = valuereference | typereference  # TODO: consider object references from 12.1
 
     # values
     # BUG: These are badly specified and cause the grammar to break if used generally.
@@ -280,7 +283,18 @@ def _build_asn1_grammar():
     assignment = type_assignment | value_assignment
     assignment_list = OneOrMore(assignment)
 
-    module_body = (assignment_list | empty)
+    assigned_identifier = Optional(object_identifier_value | defined_value)
+    global_module_reference = module_reference + assigned_identifier
+
+    symbol = Unique(reference)  # TODO: parameterized reference?
+    symbol_list = Group(delimitedList(symbol))
+
+    symbols_from_module = symbol_list + Suppress(FROM) + global_module_reference
+    symbols_from_module_list = OneOrMore(symbols_from_module)
+    symbols_imported = Optional(symbols_from_module_list)
+    imports = Optional(Suppress(IMPORTS) + symbols_imported + Suppress(';'))
+
+    module_body = (imports + assignment_list) | empty
     module_defaults = Suppress(tag_default + extension_default)  # we don't want these in the AST
     module_identifier = module_reference + definitive_identifier
     module_definition = module_identifier + DEFINITIONS + module_defaults + '::=' + BEGIN + module_body + END
@@ -326,6 +340,8 @@ def _build_asn1_grammar():
     definitive_identifier.setParseAction(annotate('DefinitiveIdentifier'))
     definitive_number_form.setParseAction(annotate('DefinitiveNumberForm'))
     definitive_name_and_number_form.setParseAction(annotate('DefinitiveNameAndNumberForm'))
+    imports.setParseAction(annotate('Imports'))
+    assignment_list.setParseAction(annotate('AssignmentList'))
 
     return module_definition
 
index 18d57af..766a0e0 100644 (file)
@@ -127,17 +127,16 @@ class SemaNode(object):
 
 class Module(object):
     def __init__(self, elements):
-        print(elements)
-        module_reference, definitive_identifier, _, _, _, module_body, _ = elements
-        _assert_annotated_token(module_reference)
-        _assert_annotated_token(module_body)
-
-        # Ignore the definitive identifier for now,
-        # maybe expose it from Module if it comes to any use.
+        self._user_types = {}
 
+        module_reference, _, _, _, _, module_body, _ = elements
         self.name = module_reference.elements[0]
-        self.assignments = [_create_sema_node(token) for token in module_body.elements]
-        self._user_types = {}
+
+        if module_body.elements:
+            _, assignments = module_body.elements
+            self.assignments = [_create_sema_node(token) for token in assignments.elements]
+        else:
+            self.assignments = []
 
     def user_types(self):
         if not self._user_types:
diff --git a/testdata/imports.asn b/testdata/imports.asn
new file mode 100644 (file)
index 0000000..eca72ba
--- /dev/null
@@ -0,0 +1,17 @@
+TEST DEFINITIONS ::=
+BEGIN
+
+-- Try imports of various forms
+IMPORTS
+informationFramework
+        FROM UsefulDefinitions {joint-iso-itu-t(2) ds(5) module(1)
+        usefulDefinitions(0) 3}
+
+ATTRIBUTE
+       FROM InformationFramework informationFramework
+;
+
+-- Must have assignments if there are imports
+value INTEGER ::= 1
+
+END