Recent

Author Topic: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?  (Read 12735 times)

edvard

  • Full Member
  • ***
  • Posts: 172
OK, I've run into this a couple of times now, and I need to know what the answer is...
If I have a procedure/function that utilizes an object, standard procedure is:

Code: [Select]
var
  SomeThing: TSomeType;
Begin // or Procedure, or Function, whatever
  SomeThing := TSomeType.Create;
  Try
    Do stuff;
  Finally
    SomeThing.Free;
  End;
End;

Right?
Trouble is, if there is an 'If..Then..Else' in the 'Do Stuff' part, it gives me the "EXCEPT" expected but "ELSE" found error.  I've been through the docs, and can't figure what is going on.  I thought at first that the commands in the 'Do Stuff' section was generating an error, which 'Try' would then expect an 'Except' to handle the error, but I made sure that wasn't it.  Perhaps an 'If..Then..Else' inherently generates exceptions due to it's nature?  I don't know.

Here is some test code; try and compile it, and see the error it gives.  Then comment the 'If...' and 'Else...' lines and see what it does.

Code: [Select]
program aint_misbehavin;

{$mode objfpc}

uses
  classes;

var
  somevar: tstringlist;

begin
  somevar := tstringlist.create;
  somevar.add('what is this');
  somevar.add('i dont even');
  try
    writeln(somevar[1]);
    if somevar[1] = 'shut up' then
      writeln('take my money');
    else
      writeln('its a trap');
  finally
  somevar.free;
  end;
end.

If I try to put the 'If..Then..Else' stuff right after 'Finally', it says "END" expected, but "ELSE" found ...

What am I doing wrong?
 %)
« Last Edit: December 24, 2014, 04:45:37 am by edvard »
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #1 on: December 24, 2014, 05:05:44 am »
It happens because you put a semicolon before else.

edvard

  • Full Member
  • ***
  • Posts: 172
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #2 on: December 24, 2014, 05:20:01 am »
How many times do I have to be bitten by this before I understand that Pascal's semicolon rules are of the devil?  >:D

I figured it out, see here:

Code: [Select]
writeln('take my money');

That semicolon isn't supposed to be there in a 'If..Then..Else' statement.  I really wish FPCs error messages were more helpful sometimes...

I'll leave this here as a warning to anyone else who gets bitten by this.  O:-)

EDIT: posted the same time as you did, Typo.  Thanks for the answer though...  8)
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #3 on: December 24, 2014, 05:27:22 am »
Basically compiler "thinks' that the "if" statement ends on that semicolon and search for "except" or "finally". And it does not reach it, but reaches "else". So it says: "Else instead of Except".

Leledumbo

  • Hero Member
  • *****
  • Posts: 8739
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #4 on: December 24, 2014, 05:56:10 am »
How many times do I have to be bitten by this before I understand that Pascal's semicolon rules are of the devil?  >:D
If you can't bear the rule, always use begin-end for every construct.

TinSoldier

  • Newbie
  • Posts: 4
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #5 on: December 24, 2014, 04:02:19 pm »
It's good to know that even Pascal can suffer from the same mis-design as C.


Leledumbo

  • Hero Member
  • *****
  • Posts: 8739
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #6 on: December 24, 2014, 06:33:25 pm »
It's good to know that even Pascal can suffer from the same mis-design as C.
Both are born in the same era, and can't escape some of its original sins easily.

edvard

  • Full Member
  • ***
  • Posts: 172
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #7 on: December 25, 2014, 12:49:52 am »
Guys, don't get me wrong; I love Pascal, it's the only language I've really been able to grasp in a meaningful capacity.  I do understand the why of this particular syntax ("a semicolon is a separator not a terminator") but at times like this, I'd like the compiler to tell me what's really wrong, instead of what it expects to be wrong.  I'd like it to warn me that I've put a semicolon in an If..Then instead of flipping out because "End" seems to be misplaced.  Maybe that's what the compiler sees as wrong, and maybe that's correct, but it's certainly not helpful.

Back to taking over the world...
 8)
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #8 on: December 25, 2014, 01:15:50 am »
Surely it is some kind of generic message, which appears for a huge number of cases, maybe the message could be more specific, but it do is helpful if you understand what it means.

You do need to learn the FreePascal modus operandi in order to use it well.
« Last Edit: December 25, 2014, 01:34:08 am by typo »

TinSoldier

  • Newbie
  • Posts: 4
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #9 on: December 25, 2014, 02:59:25 am »
The computer doesn't know what you mean, only what you actually say. Once it sees the semicolon at the end of the statement after if ... then ..., then it thinks that the if statement is complete and forgets it completely. The next token it expects is either another statement or because it's within the try statement an except statement.

I'm not a Pascal expert (I'm here to learn too), but I've seen this bug reported often in brace languages like C. This bug probably would have burned me too!

Leledumbo

  • Hero Member
  • *****
  • Posts: 8739
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #10 on: December 25, 2014, 11:10:50 am »
Error diagnostics in parsing is still a good research topic. Most commercial compilers don't even produce readable one. FPC already does a good job, as it produces much more readable error messages than Turbo Pascal/Delphi (which only consists of line number info + extremely short error message). In C family world, only Java and Clang has managed to a better level, GCC is one step behind though already a lot better than MSVC.

If you ever learned about programming language parsing, you'll know that what the compiler sees at one point is not what we see (we always see as a whole). Yes, it can be improved, but you need to be a parser writer expert. There are times when multiple possibilities exist, so the compiler can't tell you exactly what's wrong. In the OP case:
Code: [Select]
try
    writeln(somevar[1]);
    if somevar[1] = 'shut up' then
      writeln('take my money');
    else
      writeln('its a trap');
  finally
  somevar.free;
  end;
When the parser encounters semicolon in the if body after writeln, it considers the if statement has finished, as the syntax says. Next, since the parser knows it's inside a statement list after a try statement, after the semicolon it expects either another statement or an except keyword or a finally keyword. But instead of either of those 3, the compiler meets else keyword, which is why it emits the error message. Certainly the error message can be extended to write all 3 possibilities (feel free to do so for those who can and is willing), or even suggests to remove the semicolon since it meets else right after it finishes parsing an if statement (heuristic error message). Just to tell you there are cases when the possibilities are 6 or perhaps more, and this could make the error message superfluous and suggestions are too long to be written.

This is how the compiler sees and parses your code.

MathMan

  • Sr. Member
  • ****
  • Posts: 325
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #11 on: December 25, 2014, 11:18:19 am »
It's good to know that even Pascal can suffer from the same mis-design as C.
Both are born in the same era, and can't escape some of its original sins easily.

Well yes one can call that a sin from the past - but considering the alternative for a still parsable Pascal

Code: [Select]
if( humblebee ) then
begin
  singlestatement;
end else begin
  anothersinglestatement;
end;

I personally am convinced that more users would complain  ;)

So, yes, not a good design choice but probably better than the alternative ...

Leledumbo

  • Hero Member
  • *****
  • Posts: 8739
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #12 on: December 25, 2014, 11:30:54 am »
Actually
Code: [Select]
if( humblebee ) then begin
  singlestatement;
end else begin
  anothersinglestatement;
end;
Is my preference ;)
I personally am convinced that more users would complain  ;)
Certainly, but for maintenance reason, those who are experienced will do it. Why? Statements get added and removed by time. If you keep adding and removing that begin-end pair as well, it would be a hell. Keeping it there from the start will save you from silly mistyping.

serbod

  • Full Member
  • ***
  • Posts: 142
Re: If-then-else inside try-finally; "EXCEPT" expected but "ELSE" found... ?
« Reply #13 on: December 25, 2014, 12:25:26 pm »
Maybe, simple compiler hint (or warning) on semicolon followed by 'else' can solve this problem.

 

TinyPortal © 2005-2018