3 ms·
For the Fortran parser in f18 ("LLVM Flang"), I ended up writing a small suite of C++17 constexpr parser combinators to build a recursive descent parser over a
by pklausler 4y ago
For the Fortran parser in f18 ("LLVM Flang"), I ended up writing a small suite of C++17 constexpr parser combinators to build a recursive descent parser over a well-cooked character stream. A grammar encoded with parser combinators is no less readable than the input to a parser generator, and has the advantages that you can easily automate the construction of a strongly typed parse tree, perform custom error recovery, enable and disable language features, and use custom token recognizers for some of the ancient weirdness that makes Fortran so fun.
One thing that I did this time that turned out to be a good idea: run all source preprocessing and file inclusion first, before doing any parsing; deal with continuation lines and comments, and put the "cooked" character stream that results into a single contiguous block of characters, and use that for parsing. It's really fast, and makes backtracking trivial. Add a data structure that maps every character in the cooked stream back to its source provenance (input file, macro expansion, whatever) and you can get derive good source locations for error messages from just a basic char pointer. (Add a reverse mapping and you've got the basis of an IDE's language server, too.)
TL;DR: Build-time parser combinators are worthy of your consideration for your next parsing task.