Genivia / RE-flex

A high-performance C++ regex library and lexical analyzer generator with Unicode support. Extends Flex++ with Unicode support, indent/dedent anchors, lazy quantifiers, functions for lex and syntax error reporting and more. Seamlessly integrates with Bison and other parsers.
https://www.genivia.com/doc/reflex/html
BSD 3-Clause "New" or "Revised" License
522 stars 85 forks source link

Support for `-fno-exceptions` consumers #134

Closed KFAFSP closed 1 year ago

KFAFSP commented 2 years ago

I had been using v3.0.1 until very recently to embed in a project that disables exceptions. In hindsight, I'm not sure why it ever compiled, but moving to different build environments showed me that this is invalid because of the use of throw statements in the abslexer.h and absmatcher.h public includes that somehow were not flagged before.

As far as this interface is concerned, I have been able to continue quite comfortably by moving to std::abort for the std::bad_alloc exceptions, and by overriding lexer_error as appropriate.

However, this led me to the question of what a proper solution should look like. I know that RE-flex matchers propagate exceptions outwards, which means that offering a configure switch to somehow substitute them would be breaking. However, for the lexer use case, my hack seems to fare well. Alternatively, I'd have to encapsulate the lexing part in a library target with exceptions and expose an exception-free interface to the rest of the project explicitly.

I'd like to hear your thoughts on this, so that I can take proper actions to continue using this great library. I'd also be willing to contribute if this turns out to be something that should be handled on this end.

genivia-inc commented 2 years ago

Perhaps some build configuration option could work, though that is tricky for .h/.hpp files. How about a compile-time -D define?

A -DNOTHROW could replace the throw with std::abort or perhaps invoke a user-supplied function with -DTHROW=myhandler so that -DNOTHROW is -DTHROW=std::abort.

KFAFSP commented 2 years ago

I was hoping for something like that, yes. Although thinking about it now, probably using a builtin feature test macro like __cpp_exceptions would be the better option, since it'd "just work". Starting with C++98, that is, but I guess RE-flex already requires a newer standard anyways. I don't know about MSVC compatibility though, my guess is that won't work there.

I may try this in a fork soon and report back.

genivia-inc commented 2 years ago

Have you been able to try this out? Suggestions/recommendations to share?

KFAFSP commented 2 years ago

Unfortunately, I had to drastically shift focus and could not continue my front-end work. Returning to it now (after several version bumps from many components), I find myself unable to reproduce this issue! I guess I shouldn't complain when everything works, but I am farily certain that I'll run into it again at a later date. I'm sorry about this.

As a side note, I had been using my own CMake Find Module before, since I had started using REflex before CMake config support was in place. Maybe this was/is related to that way of including the targets. For future reference, I'll attach it here: https://gist.github.com/KFAFSP/8ca884738f4558df29a3b32e47730306

Maybe it can be useful to you, too. It adds the two macros that the flex/bison CMake modules provide, so I was able to use REflex as a drop-in replacement with old projects. I used a different naming scheme for the REflex targets though.

Feel free to close as stale.

sgothel commented 1 year ago

Thank you for the FindREflex

sgothel commented 1 year ago

Robert, thank you for this very elaborated "lex" solution! Testing it as an replacement and eager to read your FSM/DSA code.