0

I'm making a parse tree in Bison. Currently I have one class for each non-terminal and one subclass for each production. The problem is that I have one header for each class, so they are a lot. The solution I thought is to made a common header that includes all the headers.

Example of current project structure:

-ast
--program.hh
--decl.hh
--..
--..
--..
--constants.hh

The common header (say common_header.hh) looks like:

#ifndef COMMON_HEADER_HH
#define COMMON_HEADER_HH
#include "program.hh"
#include "decl.hh"
// a lot of includes here
#include "constants.hh"
#endif //COMMON_HEADER_HH

So in Bison I just include #include "common_header.hh", the problem is that I read that this is considered bad practice because it can produce an overhead and increment compilation times. Is this case justified to make this? The parser will always use all the headers.

Chromz
  • 183
  • 3
  • 11
  • 2
    If the compiler [precompiles headers](https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html), then a common header is often the best overall. Fwiw, what you're describing is not an AST. It's a parse tree. If you're writing a complier, you want the AST instead. – Gene Feb 25 '18 at 03:01
  • @Gene: The CST/AST distinction is less useful than you might expect. See https://stackoverflow.com/a/1916687/120163. And the physical representation of a parse tree or an AST might be identical. – Ira Baxter Feb 25 '18 at 09:47
  • @IraBaxter I've built a few compilers and tried both. The AST made a cleaner implementation. – Gene Feb 26 '18 at 14:12

1 Answers1

1

In C++ (and C), it is good practice to minimize the size of each translation unit to a reasonable extent. Creating a single header file which includes many others is usually a poor practice.

However, you seem to be describing a case where any translation unit which includes any of this group of headers will need to include the entire group of headers. In such a case, it doesn't matter whether you include them all directly vs indirectly via a single monster header.

Still, it only makes sense to create the monster header if it will be used in many translation units. If it's only going to be included in one translation unit, there's no advantage vs explicitly including all the headers there.

One other potential advantage of the monster header is that you might be able to generate it at build time given that you already have a list of the Bison grammar files somewhere in your build system. But this is quite a minor convenience, because adding a new grammar file is not useful until you add code which uses it.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436