------art_1458_27171303.1140371632402
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hi guys,

After messing up with racc for a couple of hours I realized that most of the
parse functions look pretty much the same, so I thought of stretching my
metaprogramming muscles and I wrote my first meta_parse function.

require  'strscan'

def meta_parse(*ary)
  case_str = <<ENDSTRING
    def parse(str)
      @q = []
      scanner = StringScanner.new str
      until scanner.empty?
        case
ENDSTRING

  ary.each do |type, exp, meth|
    if meth
      case_str << "         when m = scanner.scan(#{exp}) ; @q << [:#{type},
m.#{meth}]\n"
    else
      case_str << "         when m = scanner.scan(#{exp}) ; @q << [:#{type},
m]\n"
    end
  end

case_str <<<<END_STRING
        end
      end
      @q << [false,false]
      do_parse
    end
END_STRING
eval case_str
end

Here is a usage example:

meta_parse [:A, '/a/'], [:NUMBER, '/\d+/', :to_i], [:WS, '/(\s|\t)+/']
parse("a   aaa 12132 ").each{|type,val| puts "#{type}: '#{val}'"}

I would like to hear your comments on it, but please be gentle ;-)

Cheers,
Ed
--
Encontra "Tu psicóðata favorito" http://tuxmaniac.blogspot.com

Thou shalt study thy libraries and strive not to reinvent them without
cause,
that thy code may be short and readable and thy days pleasant and
productive.
-- Seventh commandment for C programmers

------art_1458_27171303.1140371632402--