After the preprocessor is done with the macro expansion, the compiler sees this:
int main()
{
printf("%s\n","printf(\"yes\")");
printf("%s\n","f(1,2)");
}
This is a common technique to layer in an "extra" indirection to control when you get stringification and when you get actual macro evaluation.
Basically, macro evaluation happens from the "outside in", not the other way around. The wikipedia page says "parameters are not parsed for macro replacement first" which I believe is refering to the same thing.