The expected grammar for the following should be clear (not sure if it is formalized, but that could be done, and the ambiguity would remain):
if true then A := b c
What is the error?
Is there a semicolon missing, and c is a function that can be called (next statement)?
Or is there an operator missing? b + c
Or a dot b.c ?
Or a parenthesis? b is a function and should take c as argument? b(c ...)
Or a begin of comment? "// c" and the expression continues on the next line?
Or a space that shouldn't be bc is an identifier?
Or an "else"?
I'm going to take this on just for fun...
Before anything, I have and still acknowledge that some errors can lead to syntactic ambiguities that will make issuing an accurate error message very difficult and, in a few cases, even impossible.
In the example you provided and given a formal grammar, the compiler can unambiguously resolve most of your questions. Here is how:
1. The compiler should know whether or not "b" is a function, if "b" is a function that takes parameters (the compiler should know that too) then a parenthesis is missing.
2. if "b" is a record (something the compiler should know) then, if there is a field in the record named "c" then the compiler emit an error stating that a dot is missing. if "b" is not a record and not a function and "b" and "c" are compatible types then the compiler can presume an operator is missing an emit a message to that effect.
3. The compiler requesting a semicolon after "b" is _always_ incorrect because adding a semicolon after "b" does _not_ make the statement correct (unlike requesting a dot or parenthesis or operator)
4. Complaining about an additional space would be incorrect because if that was the error then "b c" should be followed by one of: a semicolon, an "end" or "else" and it is not, therefore that is ruled out.
The compiler should know, at all times, no exception _ever_, where it is standing in the grammar. It also knows the type of every identifier (an unknown identifier has an unknown type, therefore it knows it's an unknown identifier, therefore an unknown type.)
In the great majority of cases, in the presence of a formal grammar, the compiler has all the information it needs to emit a crystal clear, unambiguous error message.
That said, yes, there are times when a syntactic error can create ambiguities that are not decidable. In that case the compiler should emit a message stating a couple of possible alternatives (yes, it should be able to do that too.)