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

Refactor smiles parsing code to use C++ lexer and parser #7015

Open
whosayn opened this issue Jan 1, 2024 · 0 comments
Open

Refactor smiles parsing code to use C++ lexer and parser #7015

whosayn opened this issue Jan 1, 2024 · 0 comments

Comments

@whosayn
Copy link
Contributor

whosayn commented Jan 1, 2024

Is your feature request related to a problem? Please describe.
flex and bison have supported C++ lexers and parsers for a while now, and they've matured to a point where we shouldn't have to do things like set up input strings, use unions to define token types, and handle cleanup after parsing failures. we should try to utilize the available C++ abstractions to make the smiles parser more readable and maintainable

Describe the solution you'd like
I think the following should be achievable:

  • more informative error messages when parsing fails
  • reduce the need to anticipate bad inputs in order to prevent memory leaks
whosayn added a commit to whosayn/rdkit that referenced this issue Jan 1, 2024
This refactors the smiles parsing procedure to separate the parsing and
ROMol construction procedures. Given the intricate nature of the mol
construction procedure, a 1D list of mol events made the most sense as
the parsers output. This allowed me to ensure that the order in which
atoms/bonds are created and properties are set follows that from the
previous implementation.

I also added a new project to External/flex (source:
https://github.com/westes/flex) because C++
scanners generated by flex require the FlexLexer.h header. We need this
to be present whether users have flex installed or not, and this was the
easiest way to achieve that.

Summary of changes:
        * Updated parsing-related error messages to point to the bad
          token and to include more informative messages. Eg.
            `
            [16:26:38] SMILES Parse Error: check for mistakes around position 13
            COc(c1)cccc1C#
            -------------^
            syntax error
            `

            `
            [16:27:32] SMILES Parse Error: check for mistakes around position 1
            [Bg]
            -^
            unsupported atom symbol
            `
        * Removed manual memory management from the ROMol construction
          procedure by using RAII classes (this doesn't apply to ing closures)
        * This also removes bad interactions between consecutive smiles
          parsing, which required conversion of bad inputs to follow a
          reset global state. See refactored SmilesParse::test.cpp::testFail
        * Fixes bugs like:
                * preventing hydrogens with defined chiralities
                * allowing branch atoms of the form `C1(.C1)`
                * allowing ring bonds like `C1.C%01`
                * restricting formal charges to -15 <= N <= 15

An important concern for this change is performance, so I ran all of the
tests in SmilesParse::test.cpp x1000 and noticed that this change
increases the runtime by about 5% i.e. from about 82ms to 86ms.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant