C and C++ have a number of constructs that make the grammar ambiguous and the source hard to parse. As a result, C and C++ parsers cannot be purely context-free and needs to consult symbol tables or use disambiguation.
Pointer/Typedef
Perhaps the most well-known. Is the following
a * b
a multiplication or a pointer (if a is a type)?
Sizeof
See: sizeof is surprisingly difficult to parse in c
sizeof is either a unary operator, or a parenthesized type name.
Example:
sizeof(int){0}Is it
(sizeof(int)){0}or
sizeof((int){0})where (int){0} is compound literal?
C++ Templates and >>
Another well-known example. E.g. std::vector<std::vector<int>>
C++ Attributes Vs Array index/nested Lambda
Example:
int f() {
int array[5];
// failed to compile
return array[[](){ return 0; }()];
}