How did C-Lion approach pre-compiler (#ifdef, #define and macro) support?


I'm developing a commercial plugin for SystemVerilog (SV). "Unfortunately" SV supports a pre-compiler step (for `#ifdef`, `#define`, `#include` and text macro substitution). It's not clear to me how to best support this.

C-lion is supporting this -- It would be great to hear their approach in some details.

My current attempt is to define the pre-compiler as a separate (but integrated) language with a BNF. Then use language injection, and `ILazyParseableElementTypes` so I can work above the lexer level to try to resolve the information.

This approach is turning out to be a lot more involved than I had hoped and feels like I'm working against the structure of IntelliJ, so is this is the right approach?

The main issue is that pre-compiler commands can happen anywhere in the code so cannot be coded directly in the BNF. I would love to have a global BNF rule saying that text macros can happen "anytime." and to resolve them first. 

Some technical info: I'm using Kotlin and based my code on the Rust project. I have over 500 tests running in regression. Pre-Compiler support is the main hurdle left before public beta

So my questions are:

1. How did C-Lion approach supporting the pre-compiler (specifically #ifdef, #define and macro resolution)?

2. Has any other (open source?) language implemented it? 

Comment actions Permalink


CLion uses a special implementation of a lexer that is able to expand #include directives as though they are located in the original file. Since CLion is a commercial product, there is no source code available. And I'm afraid, I'm not aware of other open source projects that have similar functionality.

Comment actions Permalink


Thank you for answering. I apologize for the slow response - I was on vacation and just got back to this.

I think the community would love to know more details about how the CLion lexer works. I understand that CLion is not available as open-source, but perhaps you could highlight relevant parts of how you implemented the pre-processor lexer? It could help with getting a lot of other languages implemented. 

Not having an example on how to do a pre-processor makes implementing it with a small external team hard!


Comment actions Permalink

Asking purely out of curiosity -- wouldn't that approach in CLion reindexing of all dependent files on any change of a header file?


Please sign in to leave a comment.