Skip to main content

Module parse

Module parse 

Source
Expand description

A recursive-descent parser for the whole C99 grammar.

§The lexer hack

C cannot be parsed without knowing which identifiers are typedef names: T * x; is a declaration when T names a type and a multiplication otherwise, and (T)-1 is a cast rather than a subtraction. The parser therefore keeps a stack of scopes recording, for every identifier it declares, whether it was introduced by typedef or as an ordinary object. Lookups walk the stack from the innermost scope out, so an ordinary declaration properly shadows an outer typedef.

§Declarator resolution

Declarators are turned into a Type tree as they are parsed, using the classic “parse the suffixes first, then recurse into the parenthesised declarator” trick. That is what makes int (*fp[3])(void) come out as array of 3 pointer to function(void) returning int rather than as an opaque chain that sema would have to interpret again.

§Standards

The grammar is C23’s, and the Standard the unit was compiled with gates the parts of it a block’s own revision does not have. Which way a construct is gated depends on how C spelled it: the C11 keywords all start with an underscore, which C99 reserves, so the lexer recognises them everywhere and the parser reports “‘_Static_assert’ requires C11 or later” instead of a syntax error; the C23 keywords are ordinary identifiers before C23 — the bundled <stdbool.h> writes #define bool _Bool — so they are gated where the name turns out not to mean anything, here and in sema.

§Error recovery

A syntax error aborts the current external declaration (Err(Bail) unwinds to the top level), which then synchronises on the next ; or } at nesting depth zero and keeps going. That way one compilation reports one error per broken declaration instead of stopping at the first.

Structs§

Bail
Signals that the current external declaration cannot be parsed further.
DeclaratorResult
The outcome of parsing one declarator.

Constants§

NORETURN_BUILTIN
The spelling of _Noreturn that every standard accepts.

Functions§

parse
Parses a token list into a TranslationUnit.