Please help with my string parser

A

Andreas Habel

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,474
Latest member
AntoniaDea

Latest Threads

Top