Adventures of a Programmer: Parser Writing Peril XXVII

The Infamous Dangling Else

The Wikipedia-page describes it well enough, so no description of the problem is laid down in this post, only a short one of the solution chosen.

There are basically two different solutions:

  1. Follow Eelco Visser’s proposals (PDF!) and do some “magick”
  2. Write an unambiguous language

We choose b.

There are some less elegant solutions (Pascal’s BEGIN / END, Shell script’s endif and others) and some more elegant ones. The most elegant solution, in my humble opinion, which counts because it is my language, is the “bracketing”: just make the brackets around the statements non-optional.
Don’t do something highly ambiguous like

if(a)
  if(b)
    do_a;
else
  do_c;

But use bracket-fences instead and do it always:

if(a){
  if(b){
    do_a;
  }
} else {
  do_c;
}

It has the advantages of not looking ugly like some of the other solutions, allows for easy handling by editors (even the more basic editors have some kind of bracket-pairing, some of the more advanced can fold everything between a pair of brackets in), and does not need any special parser-massages which most have but others might not and all do it it in a more or less different way.

The ABNF grammar for the above way to avoid the Dangling Else is

if-statement   = IF "(" expression ")" "{" statement "}" 1*else-statement
else-statement = ELSE "{" statement "}"

It might annoy some users but it is much less annoying than making whitespace a forged integral element of your syntax. Oh, look, there’s Guido van DibblerRossum, say hi to the inventor of Python!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s