Argument parsing with embedded parentheses


#1

Hello,

Can someone please point me at a simple recipe for
parsing a parameter list with embedded parentheses
and commas, e.g.,

class String
def get_args
split(’,’).map{|e| e.strip} # naive recipe
end
end

require ‘test/unit’

class TestArgumentParser < Test::Unit::TestCase
def test_simple_cases
assert_equal %w[ a b ], ‘a,b’.get_args
assert_equal %w[ a_frog b25 ], ‘a_frog, b25’.get_args
end
def test_embedded_parens
assert_equal %w[ a(1) b ], ‘a(1), b’.get_args
assert_equal %w[ a b(i) ], ‘a, b(i)’.get_args
end
def test_embedded_parens_with_commas
assert_equal %w[ a(0,j) b ], ‘a(0,j),b’.get_args
assert_equal %w[ a() b(j,k) ], ‘a(),b(j,k)’.get_args
assert_equal %w[ c(i,j,t(1)) ], ‘c(i,j,t(1))’.get_args
end
end

Thanks,


#2

On Apr 17, 2006, at 6:50 AM, Bil K. wrote:

Hello,

Can someone please point me at a simple recipe for
parsing a parameter list with embedded parentheses
and commas, e.g.,

I think StringScanner makes this kind of work fairly simple:

require “strscan”

class String
def get_args
scanner = StringScanner.new(self)
result = scanner.eos? ? Array.new : [""]
paren_depth = 0

 until scanner.eos?
   if scanner.scan(/[^(),]+/)
     # do nothing--we found the part of the argument we need to add
   elsif scanner.scan(/\(/)
     paren_depth += 1
   elsif scanner.scan(/\)/)
     paren_depth -= 1
   elsif scanner.scan(/,\s*/) and paren_depth.zero?
     result << ""
     next
   end

   result.last << scanner.matched
 end

 result

end
end

require ‘test/unit’

class TestArgumentParser < Test::Unit::TestCase
def test_simple_cases
assert_equal %w[ a b ], ‘a,b’.get_args
assert_equal %w[ a_frog b25 ], ‘a_frog, b25’.get_args
end
def test_embedded_parens
assert_equal %w[ a(1) b ], ‘a(1), b’.get_args
assert_equal %w[ a b(i) ], ‘a, b(i)’.get_args
end
def test_embedded_parens_with_commas
assert_equal %w[ a(0,j) b ], ‘a(0,j),b’.get_args
assert_equal %w[ a() b(j,k) ], ‘a(),b(j,k)’.get_args
assert_equal %w[ c(i,j,t(1)) ], ‘c(i,j,t(1))’.get_args
end
end

END

Hope that helps.

James Edward G. II


#3

James Edward G. II wrote:

Hope that helps.

It does more than help; the tests pass!

3 tests, 7 assertions, 0 failures, 0 errors

Thanks,

Bil
http://fun3d.larc.nasa.gov

P.S. I really hate working in with Open Source – I get
more help than I asked for within 2 hours! I bet my
vendor wouldn’t have even been open yet. :wink:


#4

Hi,

How about parsing a parameter list with embedded white space between two
words and EOF?

Thanks,


#5

QApassion wrote:

Hi,

Hello.

How about parsing a parameter list with embedded white space between two
words and EOF?

Whoa… I posted that one back in April?

Thanks though,


#6

The below works, excpet for the case highlighted, but its a start!

j`ey
http://www.eachmapinject.com

class String
def get_args
(split(/(.[^(].),(.[^)].)/) - [""]).map{|e| e.strip}
end
end
require ‘test/unit’

class TestArgumentParser < Test::Unit::TestCase
def test_simple_cases
assert_equal %w[ a b ], ‘a,b’.get_args
assert_equal %w[ a_frog b25 ], ‘a_frog, b25’.get_args
end
def test_embedded_parens
assert_equal %w[ a(1) b ], ‘a(1), b’.get_args
assert_equal %w[ a b(i) ], ‘a, b(i)’.get_args
end
def test_embedded_parens_with_commas
assert_equal %w[ a(0,j) b ], ‘a(0,j),b’.get_args
assert_equal %w[ a() b(j,k) ], ‘a(),b(j,k)’.get_args ## doesnt work
assert_equal %w[ c(i,j,t(1)) ], ‘c(i,j,t(1))’.get_args
end
end