[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Please help with my string parser

Eric Mahurin

5/18/2005 8:10:00 PM

You can try the following too. It has general purpose use like
yacc/lex (and ruby equivalent) and antlr, but you specify
syntax in Ruby (like your class does).

http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-t...

I'm still working on it.

Eric

--- Andreas Habel <mail@exceptionfault.de> wrote:
> 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
>
>



__________________________________
Yahoo! Mail Mobile
Take Yahoo! Mail with you! Check email on your mobile phone.
http://mobile.yahoo.com/...