use Stream qw/node drop list_to_stream/; my @tokens = ( node( OP => '+' ), node( VAR => 'x' ), node( VAL => 3 ) ); my $stream = list_to_stream(@tokens); use Data::Dumper::Simple; while (my $node = drop($stream)) { print Dumper($node, $stream); } #### $node = [ 'OP', '+' ]; $stream = [ # AoA [ 'VAR', 'x' ], [ 'VAL', 3 ] ]; $node = [ 'VAR', 'x' ]; $stream = [ 'VAL', 3 ]; # not AoA $node = 'VAL'; $stream = 3; # scalar #### my $parser = parser { my $input = shift; return unless defined $input; my $next = head($input); for my $i (0 .. $#$wanted) { next unless defined $wanted->[$i]; return unless $wanted->[$i] eq $next->[$i]; } my $wanted_value = $value->($next, $u); return ($wanted_value, tail($input)); }; #### my $parser = parser { my $input = shift; return unless defined $input; my $next = head($input); for my $i (0 .. $#$wanted) { next unless defined $wanted->[$i]; return unless $wanted->[$i] eq $next->[$i]; } my $wanted_value = $value->($next, $u); my $tail = tail($input); # is this the last token from the stream? if ($tail && 'ARRAY' eq ref $tail && 'ARRAY' ne ref $tail->[0]) { $tail = [ $tail ]; } return ($wanted_value, $tail); }; #### my $parser = concatenate( lookfor('OP'), lookfor('VAR'), ); my ( $parsed, $remainder ) = $parser->($stream); is_deeply $parsed, [qw/+ x/], 'concatenate should return the parsed values'; is_deeply $remainder, [[ VAL => 3 ]], # AoA, not just an aref '... and the rest of the stream'; #### $parser = concatenate( lookfor('OP'), lookfor('VAR'), lookfor('VAL'), );