Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi-module asn files don't work #44

Open
aholtzma opened this issue Sep 9, 2016 · 8 comments
Open

multi-module asn files don't work #44

aholtzma opened this issue Sep 9, 2016 · 8 comments

Comments

@aholtzma
Copy link
Contributor

aholtzma commented Sep 9, 2016

I've been trying to get asn1ate to digest the 3GPP RRC protocol, and I've had some success with taking snippets out and processing them individually. However the parser chokes on the whole thing:

# Auto-generated by asn1ate v.0.5.1.dev from rrc.asn1
# (last modified on 2016-09-08 23:03:47)

from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful


class BCCH_BCH_Message(univ.Sequence):
    pass


Traceback (most recent call last):
  File "asn1ate/pyasn1gen.py", line 631, in <module>
    sys.exit(main())
  File "asn1ate/pyasn1gen.py", line 622, in main
    generate_pyasn1(module, output_file, modules)
  File "asn1ate/pyasn1gen.py", line 495, in generate_pyasn1
    return Pyasn1Backend(sema_module, out_stream, referenced_modules).generate_code()
  File "asn1ate/pyasn1gen.py", line 145, in generate_code
    details = self.generate_definition(assignment)
  File "asn1ate/pyasn1gen.py", line 159, in generate_definition
    return self.generate_defn(assigned_type, type_decl)
  File "asn1ate/pyasn1gen.py", line 171, in generate_defn
    return generator(class_name, t)
  File "asn1ate/pyasn1gen.py", line 210, in defn_constructed_type
    fragment.write_block(self.inline_component_types(t.components))
  File "asn1ate/pyasn1gen.py", line 321, in inline_component_types
    component_exprs.append(self.generate_expr(c))
  File "asn1ate/pyasn1gen.py", line 167, in generate_expr
    return generator(t)
  File "asn1ate/pyasn1gen.py", line 427, in inline_component_type
    return "namedtype.NamedType('%s', %s)" % (t.identifier, self.generate_expr(t.type_decl))
  File "asn1ate/pyasn1gen.py", line 167, in generate_expr
    return generator(t)
  File "asn1ate/pyasn1gen.py", line 337, in inline_tagged_type
    type_expr += '.subtype(%s=%s)' % (tag_implicitness, self.build_tag_expr(t))
  File "asn1ate/pyasn1gen.py", line 351, in build_tag_expr
    tagged_type_decl = self.sema_module.resolve_type_decl(tag_def.type_decl, self.referenced_modules)
  File "/Users/aholtzma/src/asn1ate/asn1ate/sema.py", line 303, in resolve_type_decl
    return module.resolve_type_decl(module.user_types()[type_decl.type_name], referenced_modules)
KeyError: 'SystemInformation-BCH'

The reason is that SystemInformation-BCH is defined in the PDU-definitions module, which gets completely dropped by the parser (confirmed by running test.py --parse, I won't paste it here).

@kimgr
Copy link
Owner

kimgr commented Sep 9, 2016

It could be that dependencies are not wired between modules -- I have quite elaborate logic in place to detect dependencies and generate assignments in dependency order, not sure if this carries over to multiple modules. Also not sure how hard it would be to make that happen.

@aholtzma
Copy link
Contributor Author

aholtzma commented Sep 9, 2016

Wouldn't the dependencies be handled at the semantic level? The parse tree doesn't even have these modules.

@kimgr
Copy link
Owner

kimgr commented Sep 9, 2016

Yes, at the semantic level.

Oh, now I see you say PDU-definitions disappears from the parse tree... I think that might be because --parse only dumps the parse tree of the first module, but I'm not sure. Take a look in test.py.

@aholtzma
Copy link
Contributor Author

aholtzma commented Sep 9, 2016

Attached is a minimal test case for multi-modules with a dependency.
multi-module.asn1.txt

The result is actually different than what I see with the rrc.asn. In this case the parse sees both modules. It fails on resolving the cross module depenency though:

Boo-definitions DEFINITIONS AUTOMATIC TAGS ::=

BEGIN

  Yourenum ::= ENUMERATED { five, six, seven }

END

Foo-definitions DEFINITIONS AUTOMATIC TAGS ::=

BEGIN

IMPORTS
  Yourenum
FROM
  Boo-definitions;

  Mysequence-with-enum  ::=      SEQUENCE 
  {
    foo Yourenum DEFAULT two,
    bar ENUMERATED { a, b, c} DEFAULT c
  }

END

outputs:

WARNING: More than one module generated to the same stream.
# Auto-generated by asn1ate v.0.5.1.dev from multi-module.asn1.txt
# (last modified on 2016-09-09 16:01:43)

from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful
import foo_definitions


class Yourenum(univ.Enumerated):
    pass


Yourenum.namedValues = namedval.NamedValues(
    ('five', 0),
    ('six', 1),
    ('seven', 2)
)


# Auto-generated by asn1ate v.0.5.1.dev from multi-module.asn1.txt
# (last modified on 2016-09-09 16:01:43)

from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful
import boo_definitions


class Mysequence_with_enum(univ.Sequence):
    pass


Traceback (most recent call last):
  File "asn1ate/pyasn1gen.py", line 633, in <module>
    sys.exit(main())
  File "asn1ate/pyasn1gen.py", line 624, in main
    generate_pyasn1(module, output_file, modules)
  File "asn1ate/pyasn1gen.py", line 497, in generate_pyasn1
    return Pyasn1Backend(sema_module, out_stream, referenced_modules).generate_code()
  File "asn1ate/pyasn1gen.py", line 145, in generate_code
    details = self.generate_definition(assignment)
  File "asn1ate/pyasn1gen.py", line 159, in generate_definition
    return self.generate_defn(assigned_type, type_decl)
  File "asn1ate/pyasn1gen.py", line 171, in generate_defn
    return generator(class_name, t)
  File "asn1ate/pyasn1gen.py", line 210, in defn_constructed_type
    fragment.write_block(self.inline_component_types(t.components))
  File "asn1ate/pyasn1gen.py", line 321, in inline_component_types
    component_exprs.append(self.generate_expr(c))
  File "asn1ate/pyasn1gen.py", line 167, in generate_expr
    return generator(t)
  File "asn1ate/pyasn1gen.py", line 424, in inline_component_type
    type_expr = self.generate_expr(t.type_decl)
  File "asn1ate/pyasn1gen.py", line 167, in generate_expr
    return generator(t)
  File "asn1ate/pyasn1gen.py", line 337, in inline_tagged_type
    type_expr += '.subtype(%s=%s)' % (tag_implicitness, self.build_tag_expr(t))
  File "asn1ate/pyasn1gen.py", line 351, in build_tag_expr
    tagged_type_decl = self.sema_module.resolve_type_decl(tag_def.type_decl, self.referenced_modules)
  File "/Users/aholtzma/src/asn1ate/asn1ate/sema.py", line 303, in resolve_type_decl
    return module.resolve_type_decl(module.user_types()[type_decl.type_name], referenced_modules)
KeyError: 'Yourenum'

So I think this may be two different problems - first the parsing problem, second the inter-module hookup.

@kimgr
Copy link
Owner

kimgr commented Sep 10, 2016

Thanks for the contained repro.

I seem to recall this PR added support for emitting modules to individual files, maybe that would help here? Looks like there's a --split argument to pyasn1gen.py.

@kimgr
Copy link
Owner

kimgr commented Aug 4, 2017

Oh, now I see you say PDU-definitions disappears from the parse tree... I think that might be because
--parse only dumps the parse tree of the first module, but I'm not sure.

This turned out to be caused by a bug in the grammar. which caused the rest of the module to be consumed by the IMPORTS parser rule. I have a fix/simplification in the works.

@mungayree
Copy link

mungayree commented Feb 21, 2018

I think is still seem to occur on on cloned tree (asn1ate v.0.6.1.dev0). Is it checked in yet ?

@kimgr
Copy link
Owner

kimgr commented Feb 21, 2018

No, I don't think I ever got around to solving this entirely. It was harder than I thought, and I ran out of time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants