They give the grammar on the bottom of page 122.
dcl: optional *'s direct-dcl
Then they explain what that says in words. IOW, wherever you see dcl in an expression, you can substitute the definition for it and wherever you see direct-dcl you can substitute one of the definitions for it.
x is a name, so that's a direct-dcl
x() is therefore a direct-dcl -- by the direct-dcl() rule
*x() is a dcl, obviously
That leaves us with -- char (*(dcl))()
(dcl) is a direct-dcl
(dcl) is also a direct-dcl
That leaves us with -- char(*direct-dcl)()
*direct-dcl is a dcl
so (*direct-dcl) is a direct-dcl
Now we're down to char direct-dcl()
direct-dcl() is a direct-dcl.
I'm not completely sure what to make of char here.
So what we have here is that the function returns char. I'll leave it for you to draw out a more complete parsing tree and to work out the rest (for one thing, I gotta go to class soon). The tree will show you what is bound more closely.
And just in case, the code listings in that section are for routines to parse a function pointer declaration, plus one to construct a declaration.
And remember that the authors do say right up front that it can get confusing.
If you can get your hands on a Schaum's Outlines Programming With C
, at the end of Chapter Ten, the chapter on pointers, they provide a long list of various pointer declarations, including function pointers. In practice (we use function pointers to construct a jump table), we keep our function pointer declarations simple.