Hi,

I`ve written a short class for parsing and interpreting simple 'command 
strings'. I`m thinking about commands used in email based role playing 
games like Eressea (if someone knows)

Maybe the commands could look like this

-------------------------------------------------------------------
code = <<EOF
     BEGIN
         NAME="myName"
         VALUE = "noValue"
     END
EOF
-------------------------------------------------------------------

My class now parses this code and in the same action it has to extract 
the values.

-------------------------------------------------------------------
class Literal

     attr_reader     :expr
     attr_accessor   :childs,    :code

     def initialize( expr, code = Proc.new{} )
         @expr, @code = expr, code
         @childs = []
         yield self if block_given?
     end

     def <<( child )
         @childs << child
     end

     def exec( str )
         res = @expr.match( str )
         @code.call( res )
         return if @childs.size <= 0
         found = false
         @childs.each do |chld|
             if chld.expr.match( res.post_match )
                 found = true
                 chld.exec( res.post_match )
                 break
             end
         end
   raise "Error in Code:\n#{res.post_match.split("\n")[0]}" unless found
     end

end
-------------------------------------------------------------------

Now I need to define the grammar of my language like this (sorry for 
awful linebreaks):

-------------------------------------------------------------------
syntax['root'] = Literal.new( //, Proc.new{|*i|})
syntax['begin'] = Literal.new( /\A\s*BEGIN\s/i, Proc.new{|m| p "found 
BEGIN" } ) do |me|
                     syntax['root'] << me
                   end

syntax['name'] = Literal.new( /\A\s*NAME\s*=\s*"([a-zA-Z]*)"\s/i, 
Proc.new{|m| p "found NAME with value #{m[1]}" } ) do |me|
                     syntax['begin'] << me
                   end

syntax['value'] = Literal.new( /\A\s*VALUE\s*=\s*"([a-zA-Z]*)"\s/i, 
Proc.new{|m| p "found VALUE with value #{m[1]}" } ) do |me|
                     syntax['begin'] << me
                     syntax['name'] << me
                     me << syntax['name']
                   end

syntax['end'] = Literal.new( /\A\s*END/i, Proc.new{|m| p "found END" } ) 
do |me|
                     syntax['begin'] << me
                     syntax['name'] << me
                     syntax['value'] << me
                   end

-------------------------------------------------------------------

And at least the parsing starts with

-------------------------------------------------------------------
p syntax['root'].exec( code )
-------------------------------------------------------------------

It produces something like
"found BEGIN"
"found NAME with value myName"
"found VALUE with value noValue"
"found END"

on success, and

"found BEGIN"
syntax.rb:37:in `exec': Error in Code: (RuntimeError)
         WronName="myName"       from syntax.rb:33:in `exec'
         from syntax.rb:30:in `each'
         from syntax.rb:30:in `exec'
         from syntax.rb:64

on failure.

So far so good *g*.
This was my first try and I`m not sure if this is roughly the ruby way.
I think this gets very complicated with complex commands, so feel free 
to annotate!

Thanks,
Andreas