in reply to Re^9: parse lisp style config
in thread parse lisp style config
You have this:
my @tokens = get_tokens $string; my sub parse_list { state @tokens = @_; my @list; while (my $token = shift @tokens) { if ($token eq '(') { push @list, __SUB__->(); } elsif ($token eq ')') { return \@list; } else { push @list, $token; } } return \@list; } my $list = parse_list @tokens;
Sometimes you pass tokens to it. Sometimes you don't. That's weird and confusing. Fixed:
my @tokens = get_tokens $string; my sub parse_list { my @list; while (my $token = shift @tokens) { if ($token eq '(') { push @list, __SUB__->(); } elsif ($token eq ')') { return \@list; } else { push @list, $token; } } return \@list; } my $list = parse_list;
The lack of error checking is disturbing. Fixed:
my @tokens = get_tokens $string; my sub parse_list { my @list; while ( @tokens && $tokens[0] ne ")" ) { my $token = shift( @tokens ); if ( $token eq "(" ) { push @list, __SUB__->(); die( "Missing `)`" ) if !@token; my $token = shift( @tokens ); die( "Missing `)`" ) if $token ne ")"; } else { push @list, $token; } } return \@list; }; my $list = parse_list(); die( "Unexpected `$tokens[0]`" ) if @tokens;
Without recursion:
my @tokens = get_tokens $string; my sub parse_list { my @stack; push @stack, [ ]; while ( @tokens ) { my $token = shift( @tokens ) { if ( $token eq "(" ) { my $sublist = [ ]; push @{ $stack[ -1 ] }, $sublist; push @stack, $sublist; } elsif ( $token eq ")" ) { die( "Unexpected `)` ) if @stack == 1; pop( @stack ); } else { push @{ $stack[ -1 ] }, $token; } } die( "Missing `)` ) if @stack > 1; return $stack[ 0 ]; } my $list = parse_list(); die( "Unexpected `$tokens[0]`" ) if @tokens;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^11: parse lisp style config
by vincentaxhe (Scribe) on Dec 01, 2024 at 06:53 UTC |