Slashdot Mirror


GCC Gets PCH Support And New Parser

Screaming Lunatic writes "GCC will finally get precompiled header support which should help with faster compile times. GCC will also be fitted with a new recursive descent parser that fixes more than 100 bugs in GCC. I'm not sure how they decomposed C++ into a context free grammar so that it could be parsed using recursive descent."

9 of 83 comments (clear)

  1. ANTLR? by angel'o'sphere · · Score: 5, Informative

    Terrence Parr, the author of the antlr compiler construction tool says that most languages can be parsed with LL-k grammars provided you have a deep enough look ahead (that means 'k' is big enough).

    Basicly: you aer NOT context free but context sensitive, of course.

    Terrence showed that in practice the hughe drawbacks of a look ahead of k does not appear often.

    I would think the typical look ahead for C++ is 1 in over 85% of the cases and 2 for the rest and in rare cases 4 ... however this is a guess(stemming from java parsers which are often LL-1)

    angel'o'sphere

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  2. Re:Why the extra step? by PD · · Score: 5, Informative

    Because that sort of thing can get screwed up easily and cause all sorts of problems. I'm thinking of how Borland's precompiled headers sometimes goofed up, or my horrible experiences with Sun's cached templates on their C++ compiler. I'd rather explicitly tell the compiler exactly what I want done in terms of precompilation than to let it guess and screw up on its own.

  3. what a coincidence by Anonymous Coward · · Score: 5, Funny

    context free grammar

    This is good for slashdot, which is a grammar-free context!

  4. Standard C++ Easier by Euphonious+Coward · · Score: 5, Interesting
    ISO Standard 14882 C++ is easier to parse than ARM C++. The biggest difference is that the committee eliminated "implicit int" declarations, which eliminated a lot of ambiguities. Requiring typename in templates helped too.

    (OT) Just wait until you see C++0x. It will (probably) support variable definitions like

    auto iter = some_map.begin();
    and figure out a type for iter by looking at the result type from map<>::begin().
  5. Because implementations just got contributed by sixseve · · Score: 5, Informative

    From the gcc.gnu.org homepage news:

    January 10, 2003

    Geoffrey Keating of Apple Computer, Inc., with support from Red Hat, Inc., has contributed a precompiled header implementation that can dramatically speed up compilation of some projects.

    December 27, 2002

    Mark Mitchell of CodeSourcery has contributed a new, hand-crafted recursive-descent C++ parser sponsored by the Los Alamos National Laboratory. The new parser is more standard conforming and fixes many bugs (about 100 in our bug database alone) from the old YACC-derived parser.

  6. Re:Why the extra step? by PD · · Score: 5, Insightful

    No, object files are built one at a time with a makefile. The correlation would be if we just typed "gcc" in a directory and the compiler built every cpp file into an object. What if I didn't want a file compiled? What if that file was supposed to be copied into a directory after it was built with another tool? In that case, gcc would be doing the wrong thing by building every .o automatically.

    A makefile lets me control the building of each and every .o file myself, allowing for all sorts of things that I might want to do.

    Precompiled headers should work the same way, or they won't be as flexible as the .h files.

  7. Re:Why the extra step? by j7953 · · Score: 5, Interesting
    Why, why, why, why? Why can't the header file simply be compiled at the first inclusion and cached somewhere?

    But that's just what make will do. Why rebuild the same functionality within a different tool? Basically, the reason is (probably, I'm not a GCC developer) the UNIX philosophy of having small tools doing their job. GCC is a compiler and nothing else, make is a tool that decides what needs to be compiled.

    If you want automation, you can always use an IDE (or some other tool) that includes a make equivalent or that creates appropriate makefiles for you.

    --
    Sig (appended to the end of comments I post, 54 chars)
  8. Recursive Descent / Context Freeness by Tom7 · · Score: 5, Informative

    Just to clarify: A language does not need to be context-free in order to be parsed by a recursive descent parser, because you can augment the recursive functions with extra arguments that provide, well, context. For instance:

    [exp] ::= x | let [dec] in [exp] end | n | print [exp]

    [dec] ::= val x = [exp]

    (where x is the set of variables and n is the set of integer constants)

    This language is context-free, but the following restriction isn't: We say that strings are only in this language if variables aren't used before being declared. Legal:

    let
    val x = 3
    in
    print x
    end

    Illegal:

    let
    val x = 3
    in
    print y
    end

    This language isn't context-free (in the usual sense) but can be parsed easily by a recursive function. That function simply takes with it a list of all the declared variables. (In fact, you can pull this same sort of hack with lex/yac by having the lexer make a call into your code, which keeps a symbol table of variables it has seen as it runs.)

    (If I understand the problem with C and C++ correctly, the difficulty parsing has to do with recognizing a token as a type name or an identifier, so I think this is relevant.)

  9. Re:Well done GCC, but.... by Lumpish+Scholar · · Score: 5, Interesting
    ... in my experience, good use of forward declarations (to avoid unrequired chains of #include), combined with simply putting less in each .c file is a lot more effective than adding the complication of precompiled headers into your build process.
    My experience is just the opposite.

    Putting less into each .c file (so that changing a .c file requires less to be recompiled) is only useful if most of the code you need to compile is in .c files. Unfortunately, even with forward declarations, every .c file is likely to have thousands (or tens of thousands) of source from all the .h files that are (recursively) included; that's where the bulk of the compiled code is. Unless each of the smaller .c files can include significantly fewer .h files than the larger .c files could (which, in my experience, they can't), then doubling the number of .c files roughly doubles the amount of source code (.c files plus all the .h files per .c file) needed to compile a product.

    I haven't had a lot of luck with precompiled headers, either. (Context: a project with a hundred source files spread across a dozen directories, totalling about fifty thousand lines of source.)

    Best solution I know of for C++: Use as many forward declarations as you can, periodically trim your include directives, and have relatively large .c files. Each includes a lot of .h source, but this reduces the total bulk of what comes out of the preprocessor.

    I know of C++ systems that take a CPU week to build because of these issues!

    Note that Java doesn't have this problem, or the problem of teaching your makefile about header file dependencies. (Not important enough to get all projects to switch from C or C++, but among the reasons that some projects should.)
    --
    Stupid job ads, weird spam, occasional insight at