------ 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--