#!/usr/bin/perl -w # # skudparser -- parse something for skud # # 2001/02/28 Rich Lafferty -- initial version # # Released into the public domain. # # --------------------------------------------------------------- # Skud wrote: # # Anyone got a clever idea for how to split up the following (user input) # string into a list of subroutines with their args? # # a,b(),c(1),d(1,2,3), e, ), f(), g(1), h(1,2,3), i(1, 2, 3), j(1, 2,3), # k(","),l(","," "), m(")"), n("),") # # This should return an array with the following elements: # # a # b() # c(1) # d(1,2,3) # e # ) # f() # g(1) # ... # n("),") # # --------------------------------------------------------------- # # Note to self: *Having* a good regexp engine doesn't mean having # to *use* regular expressions. use strict; sub parse ($) { my @line = split('', $_[0]); my (@outdata, $chunk); my ($qq, $q, $p, $i) = (0,0,0,0); # ", ', ( for (@line) { $i++; # mind our p's and q's die qq|Impossible count ["$qq" '$q' ($p)] at character $i ('$_')| if $qq < 0 or $q < 0 or $p < 0 or $q > 1 or $qq > 1; # parens nest $p++ if $_ eq '(' and !$q and !$qq; $p-- if $_ eq ')' and $p and !$q and !$qq; # quotes don't nest $qq = !$qq if $_ eq q|"| and !$q; $q = !$q if $_ eq q|'| and !$qq; # ignore spaces outside of quotes next if $_ eq ' ' and !$qq and !$q; if ($_ eq ',' and !$p and !$q and !$qq) { # not inside anything so this one's a delimiter push @outdata, $chunk; $chunk = undef; next; } # keep what we've got $chunk .= $_; } push @outdata, $chunk; # no comma following last chunk! return @outdata; } # test data my $input = q|a,b(),c(1),d(1,2,3), e, ), f(" "), g(1), h(1,2,3), i(1, 2, 3), j(1, 2,3), k(","),l('","'," "), m(')'), n("),'")|; my $noquote = q|a,b(),c(1),d(1,2,3), e, ), f( ), g(1), h(1,2,3), i(1, 2, 3), j(1, 2,3), k(,),l(,, ), m()), n(),)|; my @hlagh = parse($input); for (@hlagh) { print "$_\n"; }