From: Nick Bowler Date: Tue, 18 Jul 2023 01:55:28 +0000 (-0400) Subject: Add an explanation for declaration specifier rules. X-Git-Tag: v1.3~115 X-Git-Url: https://git.draconx.ca/gitweb/cdecl99.git/commitdiff_plain/9bbe3b9dc114473daf68153769495e6a4a50b7de Add an explanation for declaration specifier rules. It took me a while to wrap my head around WTF the declaration specifier parser rules were trying to accomplish. Let's add a big explanation so hopefully, if I try to read them again after another decade or so, they will make sense more easily. --- diff --git a/src/parse.y b/src/parse.y index e9df6cb..a386c08 100644 --- a/src/parse.y +++ b/src/parse.y @@ -259,6 +259,22 @@ declaration: declspecs declarators semi { i->specifiers = $1; }; +/* + * We support parsing declarations using arbitrary identifiers as type + * specifiers (a la C typedef). To avoid confusion with identifiers that + * may also be used as declarators, note the following: + * + * (a) Every valid C declaration must have at least one type specifier, and + * (b) Valid declarations with typedef names have exactly one type specifier. + * + * So the rule applied when parsing specifiers is: an identifier is a type + * specifier only if we have not yet seen any type specifiers whatsoever + * (within one declaration specifier list). + * + * Treating identifiers as type specifiers by default can lead to strange and + * unexpected parses; libcdecl applies a simplification step to the resulting + * parse tree afterwards. + */ declspecs: declspec_notype declspecs { $$ = $1; $$->next = $2;