Phoenix.pm: Parameter parser
Hal Goldfarb
codewell at earthlink.net
Mon Dec 2 17:31:42 CST 2002
I highly approve of your coding style and modular breakdown (similar to
mine). Consistency is wonderful : )
-Hal
On Monday 02 December 2002 01:25 pm, Doug Miles wrote:
> Doug Miles wrote:
> > Doug Miles wrote:
> >> Hey all,
> >>
> >> I just implemented a parser that takes something like this:
> >>
> >> command param1 param2="value2" param3="value3 \"foo\""
> >>
> >> and puts the parameters and values into a hash. The value for param1
> >> would be "1". I'm not sure I implemented it the best way, though. I
> >> thought I'd get some ideas from you folks to get a different
> >> perspective. I'll post what I did after I get some responses. I
> >> don't want to contaminate your thinking. :)
> >
> > I left out a few details that I forgot to mention. There can be
> > optional whitespace around the '=' and command may be a command, a
> > scalar, an array, or a method call. What the program does from there
> > depends on which it is. Right now the program is putting the data in an
> > array, but this will change to a hash in the future. Oh, and ignore the
> > $tag_parser parameter. :)
> >
> > I have to pay around with Scott and Eden's examples some more, but here
> > is what I did (I'm sure the formatting will be screwed up):
>
> Thanks for the input guys. I did consider using Parse::RecDescent, but
> it seemed a little heavyweight for this application. I realized that in
> my previous program, I was putting the regexes in array context, which
> screwed up the /g \G combination:
>
> if(my ($match, $scalar) = $tag_content =~ /\G^(\$([a-zA-Z0-9_:.]+))/)
> {
>
> pos($tag_content) += length($match);
>
> }
>
> This caused me to have to manually update the position pointer. If you
> just use the numbered variables instead, everything works out:
>
> if($tag_content =~ /\G^\$([a-zA-Z0-9_:.]+)\s*/gc)
> {
>
> $scalar = $1;
>
> }
>
>
> I learned this the hard way. :)
>
> I worked on this some more, and this is what I have now:
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> use Regexp::Common;
>
> my $tag_content = '$scalar param1 param2="\"test2\""';
> my @parameters = process_tags('', $tag_content);
> print join('|', @parameters) . "\n\n";
>
> $tag_content = q{@array format="'test3'" default_format="test4"};
> @parameters = process_tags('', $tag_content);
> print join('|', @parameters) . "\n\n";
>
> $tag_content = q{%hash format="'test5'" default_format="test6"};
> @parameters = process_tags('', $tag_content);
> print join('|', @parameters) . "\n\n";
>
> $tag_content = <<"EOD";
> command
> doug =
> "test7"
> julie =
> "test8"
> EOD
>
> @parameters = process_tags('', $tag_content);
> print join('|', @parameters) . "\n\n";
>
> $tag_content = 'command "doug"="test7" julie="test8"';
> @parameters = process_tags('', $tag_content);
> print join('|', @parameters) . "\n\n";
>
> # process_tags #########################################################
>
> sub process_tags
> {
>
> my $tag_parser = shift;
> my $tag_content = shift;
>
> my $scalar;
> my $array;
> my $hash;
> my $command;
> my @parameters;
>
> print "\$tag_content: $tag_content\n";
>
> while(pos($tag_content) < length($tag_content))
> {
>
> if($tag_content =~ /\G^\$([a-zA-Z0-9_:.]+)\s*/gc)
> {
>
> $scalar = $1;
>
> }
> elsif($tag_content =~ /\G^\@([a-zA-Z0-9_:.]+)\s*/gc)
> {
>
> $array = $1;
>
> }
> elsif($tag_content =~ /\G^\%([a-zA-Z0-9_:.]+)\s*/gc)
> {
>
> $hash = $1;
>
> }
> elsif($tag_content =~ /\G^([a-zA-Z0-9_:.]+)\s*/gc)
> {
>
> $command = $1;
>
> }
> elsif($tag_content =~
> /
> \G # Start at last match pos.
> (
> ([a-zA-Z0-9_:.]+) # A parameter.
> (?:
> \s*?=\s*? # '=' & optional WS.
> $RE{delimited}{-delim=>'"'}{-esc=>'\\'}{-keep} # '"'
> delimited
> # value.
> )?\s*
> )
> /gcx # / Fix VIM syntax highlighting problem.
> )
> {
>
> my $match = $1;
> my $parameter = $2;
> my $value = defined($5) ? $5 : 1;
>
> $value =~ s/\\"/"/g;
>
> push(@parameters, ($parameter, $value));
>
> }
> else
> {
>
> die "$tag_content\n" . ' ' x pos($tag_content) . "^\n";
>
> }
>
> }
>
> return @parameters;
>
> }
>
> # program output #
>
> $tag_content: $scalar param1 param2="\"test2\""
> param1|1|param2|"test2"
>
> $tag_content: @array format="'test3'" default_format="test4"
> format|'test3'|default_format|test4
>
> $tag_content: %hash format="'test5'" default_format="test6"
> format|'test5'|default_format|test6
>
> $tag_content: command
> doug =
> "test7"
> julie =
> "test8"
>
> doug|test7|julie|test8
>
> $tag_content: command "doug"="test7" julie="test8"
> command "doug"="test7" julie="test8"
> ^
More information about the Phoenix-pm
mailing list