Well, not that much more complicated. It’s a truism about computer languages, that the most important tool is the console. What I mean is that, unless your program has a way to communicate information back to the programmer, it’s almost impossible to create working programs.

If you gave your little “Talk To Me!” program to a friend, how long would it take before he or she could guess that it only understood a double quote? Programming is like that. Without a console, you fire possiblities away at a dumb block never knowing how close any of your possiblities are.

So now we are going to modify the program to give some help to the poor friend who is trying to figure out what your program does understand.

Modify your program to add the line listed with # new:

#!/usr/bin/env ruby
# Talk To Me -- tell me something and I'll tell you if I understand it

require 'rubygems'
require 'treetop'
puts 'Loaded Treetop with no problems...'

Treetop.load 'double_quote'
puts 'Loaded double quote grammar with no problems...'

parser = DoubleQuoteParser.new

print "You say: "; what_you_said = gets
what_you_said.strip! # remove the newline at the end

if parser.parse(what_you_said)
  puts "I say yes! I understand!"
else
  puts "I say no, I don't understand."
  puts parser.failure_reason # new
end

Unfortunately, this code won’t work for every situation. Run your program and enter "You wanted a quote? I'll give you a quote!" (include the double-quotes, obviously; that’s the whole point!). What happens? You get a failure but no failure reason!

The problem is our parser understood the double-quotes all right, but it knew you didn’t stop talking, and there’s stuff it doesn’t understand at the end. So it is an error? No, not really. I mean, it did understand the double quote. It did everything you asked it to. It’s just not sure if you asked it to do something else, so got that blank look in its face again…

In the current (1.4.4) version of Treetop, you have to do some fancy footwork to diagnose the problem. Hopefully, in future versions, this kind of code will be moved inside the class.

Modify your program as shown by the # new:

#!/usr/bin/env ruby
# Talk To Me -- tell me something and I'll tell you if I understand it

require 'rubygems'
require 'treetop'
puts 'Loaded Treetop with no problems...'

Treetop.load 'double_quote'
puts 'Loaded double quote grammar with no problems...'

parser = DoubleQuoteParser.new

print "You say: "; what_you_said = gets
what_you_said.strip! # remove the newline at the end

if parser.parse(what_you_said)
  puts "I say yes! I understand!"
else
  puts "I say no, I don't understand."
  unless parser.terminal_failures.empty? # new
    puts parser.failure_reason
    else #                                 new
    puts "I had a problem with line #{parser.failure_line} column #{parser.index+1}" # new
    puts "To be honest, I was not expecting you to say anything more."               # new
  end
end

Ugly, isn’t it! Of course if you didn’t care that the user babbled on and one, you can always add this line before you parse your input:

parser.consume_all_input = false

Okay. At this point, even though we have been taking baby steps all the way, we have come quite far. We were able to write a simple Treetop grammer, connect it into Ruby, parse something with it, and we have a good sequence of code we can use in all cases to debug our grammar.

We can now start in earnest on our email list parsing program!

Previous | Next