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;
In reply to Re^10: parse lisp style config
by ikegami
in thread parse lisp style config
by vincentaxhe
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |