Because a quite different AST is built for the second case depending on whether A is a type or not. And you can't tell whether A is a type or not without a symbol table.
Personally, I wonder how many of these things would go away if pointers were a suffix operator with a different character (maybe the @ sign), and if casts looked like function calls.
A B@; # B is a pointer to type A
A(-B); # A is either a function or a type for casting
# Same AST regardlessC needs forward declarations for some things, and it needs a symbol table to resolve some parts of the grammar. All I was saying was that I think you could resolve both of them with minor changes. (I see that D has a "cast" keyword, and that's obviously one way to do it.)
IIRC that's how Pascal did it, using a caret ^ for denoting a pointer.
A pointer to type A is:
var B: ^A
The parser knows it is a declaration because of the var, and it knows ^A is the type, because of the colon. That it is a caret does not really matter here