evan.musing << current

life and tech stuff by Evan Phoenix

Helpful syntax errors

with 10 comments

Syntax errors are a part of life for programmers. The language of the computer, no matter how flexible the language, is very picky.

And thus how the language communicates back to the user about what it didn’t understand is important, because time is spent in this phase, no matter the skill level of the programmer.

In Ruby specifically, MRI’s parser (and by extension the melbourne parser Rubinius uses) use yacc, and thus suffer from syntax errors which can be particularly difficult to understand. One particular syntax error that commonly occurs is when there is an ‘end’ missing from an expression. This results in the dreaded syntax error, unexpected $end, expecting kEND message.

Here is a quick example:


class Spaghetti
  class Sause
     def add(plate)
        while more?
           plate << self
     end
  end
end

Now, this is a short example and so spotting the error is fairly easy. But this error typically occurs when you’re working on a 600 line file with multiple classes inside classes and with complicated logic, making it quite difficult to find.

This evening, I decided to try and at least help make this easier to find. So now in Rubinius, rather than

syntax error, unexpected $end, expecting kEND

you get

missing ‘end’ for ‘class’ started on line 1.

Thats a big improvement, because now first off, it’s fairly clearly communicated what is wrong, i.e. that you’ve forgotten an ‘end’. In addition, it tells you what element still required a ‘end’, in this case, a ‘class’ on line 1.

Now, this is far from perfect. It’s pointing you to the element that was unclosed, rather than the one that you actually forgot the ‘end’ on. But it at least is now pointing you to the chunk of code that is the offending code. In practice, this can be a big help.

In the future, it might be possible to try and use indentation to try and narrow down where the missing ‘end’ should be. But for now, every little bit helps.

About these ads

Written by evanphx

November 29, 2009 at 9:39 pm

Posted in Uncategorized

10 Responses

Subscribe to comments with RSS.

  1. Let’s hope this change makes it’s way to MRI as well :)

    August Lilleaas

    November 29, 2009 at 11:44 pm

  2. That is a nice improvement, Evan. Good one.

    Jamie Orchard-Hays

    November 30, 2009 at 8:17 am

  3. I like this. For some reason I was annoyed when the 1.8 series started issuing errors like this, because they are so cryptic. Even though ruby 1.6’s “parse error” contained less information, it was easier on the eyes.

    Now Rubinius gives us the best of both worlds. Nice. :)

    Paul Brannan

    November 30, 2009 at 2:00 pm

  4. What commit was this in? The JRuby parser is basically the same structure as MRI’s, so it would be nice to add some of these smarts to our parser too.

    Charles Oliver Nutter

    December 1, 2009 at 12:07 am

  5. Charles:
    That change is from commit 7537128aa905b1721a58c719d25e44604a5ed6fe

    Wilson Bilkovich

    December 1, 2009 at 2:33 pm

  6. Hi Evan,

    > In the future, it might be possible to try and use indentation to try and narrow down where the missing ‘end’ should be. But for now, every little bit helps.

    Logic Junction once made exactly what you want. I saw it at RubyKaigi2007.
    http://jp.rubyist.net/RubyKaigi2007/Log0609-LT06.html (ja)
    Unfortunately now the patch is unavailable…

    ujihisa

    December 3, 2009 at 12:36 pm

  7. To Evan and ujihisa,

    The patch has already been applied to ruby 1.9.

    with -W option, you will get the following messages for the example code.

    -:6: warning: mismatched indentations at ‘end’ with ‘while’ at 4
    -:7: warning: mismatched indentations at ‘end’ with ‘def’ at 3
    -:8: warning: mismatched indentations at ‘end’ with ‘class’ at 2
    -:9: syntax error, unexpected $end, expecting keyword_end

    Yugui

    December 4, 2009 at 5:27 pm

  8. Seems like only a minor update but it will help the debugging process dramatically. It’s always useful to find the offending piece of code as you’ve hugely reduced the area you’re looking for an error in. I’ve spent hours debugging code ust to find on missing end or an open bracket i forgot to close! So frustrating!
    Reece

    Jobs In Manchester

    August 2, 2010 at 2:00 am

  9. That’s awesome, great job.
    I wonder though if it’d be possible and then if it’d be useful if it also printed out the name of the unclosed element like so:

    missing ‘end’ for ‘class’ ‘Spaghetti’ started on line 1.

    or

    missing ‘end’ for ‘class Spaghetti’ started on line 1.

    Although easier to read/understand, would that be more helpful or is it superfluous information?

    Diego Scataglini

    August 23, 2010 at 6:50 pm

  10. Wow just realized how old is this post :D

    Diego Scataglini

    August 23, 2010 at 6:53 pm


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

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: