This eliminates some simple-declaration/function-definition false parses.
- implement a function to determine whether a declarator ForestNode is a function declarator;
- extend the standard declarator to two guarded function-declarator and non-function-declarator nonterminals;
The "dfs" doesn't actually branch anywhere, so it's just a linear walk, and I think replacing the recursion with iteration is actually more readable here.
Also, the first known kind on the walk up == the last known kind on the walk down.
So I think this can be written as:
bool IsFunction = false; // Walk down the declarator chain, innermost one wins. // e.g. (*x)() is a non function, but *(x()) is a function. for (;;) { if (Declarator->kind() != Sequence) // not well-formed, guess return IsFunction; switch (Declarator->rule()) { case noptr_declarator$$declarator_id: // reached the bottom return IsFunction; // *X is a nonfunction (unless X is a function). case ptr_declarator$$ptr_operator$ptr_declarator: Declarator = Declarator->elements()[1]; IsFunction = false; continue; // X() is a function (unless X is a pointer or similar) case declarator$$noptr_declarator$parameters_and_qualifiers$...: Declarator = Declarator->elements()[0]; IsFunction = true; continue; // (X) is whatever X is. case declarator$$l_paren$ptr_declarator$r_paren: Declarator = Declarator->elements()[1]; continue; // ... more cases ... default: assert(false && "unhandled declarator for IsFunction"); return IsFunction; } }