But how do we get
- From: The compiler found an incorrect keyword
- To: Therefore it must expect a keyword (just a different keyword)?
I didn't say it must expect a keyword. What I said is, if it finds a keyword that does not start a new statement, as in the case with "else", then the keyword must be "end". The reason for that is because the compiler is parsing a compound statement, therefore, it must expect a keyword to terminate the compound statement and, the _only_ keyword that does not start another statement that fulfills the requirement is "end".
If the keyword "else" is wrong, we can conclude something else must be expected. But that something else can be anything: A new none-empty statement, an empty statement followed by a ";", an "end".
No, it cannot be anything. What the compiler (Delphi) is saying, if you want a keyword that does not start another statement (as is the case with "else") there then it _must_ be "end". There is no other choice.
FPC stating that it expected a semicolon, in addition to being incorrect, it is also utterly useless because semicolons separate empty statements. The compiler could ask for 200 semicolons there and achieve just as much. It's asking for a semicolon is the same (in that case) as asking for a space characters. Utterly useless.
Following your argument, that the compiler should treat an unexpected keyword as a special error, then it should simply state
"incorrect keyword"
It's not a special error. A compound statement is terminated with "end". There is no reason for the compiler to go "generic" and state "incorrect keyword" when it knows that the only acceptable keyword that does not start another statement is "end". Since "else" does not start another statement then the only acceptable keyword that does not start another statement (as "else" is) is "end".
Yet, point in your favour:
repeat
while true do else
gives: Fatal: Syntax error, "UNTIL" expected but "ELSE" found
So it uses the knowledge about the outer block.
It's not so much that it uses knowledge of the outer block, once the "while" is parsed, execution returns to the "repeat" production to finish parsing it, at that time, it finds an "else". The only keyword that does not start another statement that "repeat" is going to accept is "until". Since, "else" does not start another statement, the production demands an "until" keyword, as it should.
Personally, I would like to see the "; expected" error in the last case too. Just for consistency. (As both errors are equally good)
It really shouldn't do that because, at some point the "repeat" production has to ask/demand the "until" it needs. It can't just go asking for another semicolon every time it needs an "until".
Of course, one has to ask why change the error at all.
Purely technically it is correct. (It is not complete, but it is one correct possibility, and neither would "end expected" be complete).
No, technically, it is incorrect. That's the problem, a compound statement is not ended with a semicolon, it's ended with an "end" keyword. It can't keep asking for semicolons endlessly. It really has to ask for the "end" and it has to ask for it whenever it see a symbol that does not start a new statement, whatever it may be.
The reasons to change an error message are:
1- It is plain wrong (but this is a subset of the next point)
2- The message can be improved to give the user a better idea what is wrong.
The first does not apply.
On the contrary, the first applies in full. The compound statement is not asking for its terminating symbol, that's incorrect/wrong/bad/no good/trump.
Given that ";" is statistically more likely, the "; expected" error is actually ever so slightly more helpful.
Not if the programmer wants to eventually have a program that compiles because all the semicolons in the universe put before the else aren't going to do it.
It is basically a summary of the state of the parser, not a correction advise.
Error messages are not correction advise ? ... if doing what they state isn't going to lead to a correct statement then why does the compiler bother emitting them ?... ascii visual entertainment ?...
Example: Delphi gives the exact same error for this code:
But, here is the thing you are attempting to avoid. If you follow Delphi's corrective "suggestions" (not advice, of course) you will eventually end up with a program that compiles.
Attempting to use FPC's "ascii visual entertainment" yields a request for more and more semicolons and never a program that compiles successfully.
That applies to the example you showed. I used your example. Followed Delphi's "suggestions" and after a few compiles had a syntactically correct program. If I were still following FPC's suggestion (not advice!) this entire post would be semicolons and the program would still not compile (and not ever compile.)
I think the Delphi solution is inferior.
Interesting that the solution that leads to a syntactically correct program is "inferior" while the "solution" that has the programmer adding semicolons for infinity is not inferior.
Anyway, I just wanted to know if there was interest in having correct error message. I have the answer and, have no doubt about what it is.