my $state = 'idle';
while ( my $input = <> ) {
if ( $state eq 'idle' ) {
if ( $input =~ /FOO/ ) {
$state = 'foo';
}
elsif ( $input =~ /BAR/ ) {
$state = 'bar';
}
elsif ( $input =~ ...
else { die "unknown input: $input" }
}
elsif ( $state eq 'foo' ) {
if ( $input =~ /FOO/ ) {
$state = 'foo';
}
elsif ( $input =~ ...
else { die "unknown input: $input" }
}
elsif ( $state eq ...
else { die "internal error: bad state $state" }
}
####
my $state = 'idle';
while ( my $input = <> ) {
if ( $input =~ /FOO/ ) {
if ( $state eq 'idle' ) {
$state = 'foo';
}
elsif ( $state eq 'foo' ) {
$state = 'foo';
}
elsif ( $state eq ...
else { die "internal error: bad state $state" }
}
elsif ( $input =~ /BAR/ ) {
if ( $state eq 'idle' ) {
$state = 'bar';
}
elsif ( $state eq ...
else { die "internal error: bad state $state" }
}
elsif ( $input =~ ...
else { die "unknown input: $input" }
}
##
##
use warnings;
use strict;
use Test::More tests=>2;
is_deeply parse_data('x[[[hello]]]![[[world]]]ab'),
['hello','world'];
is_deeply parse_data('x[y[[z[[[[[[[[[foo]1]]2]]]3'),
['[[[[[[foo]1]]2'];
sub parse_data {
my @indata = split //, shift; ;
my $state = 'await_start1';
my $curdata = undef;
my @outdata;
for my $c (@indata) {
if ( $state eq 'await_start1' ) {
if ( $c eq '[' ) { $state = 'await_start2' }
}
elsif ( $state eq 'await_start2' ) {
if ( $c eq '[' ) { $state = 'await_start3' }
else { $state = 'await_start1' }
}
elsif ( $state eq 'await_start3' ) {
if ( $c eq '[' ) { $state = 'in_data'; $curdata = '' }
else { $state = 'await_start1' }
}
elsif ( $state eq 'in_data' ) {
if ( $c eq ']' ) { $state = 'got_end1' }
else { $curdata .= $c; $state='in_data' }
}
elsif ( $state eq 'got_end1' ) {
if ( $c eq ']' ) { $state = 'got_end2' }
else { $curdata .= ']'.$c; $state='in_data' }
}
elsif ( $state eq 'got_end2' ) {
if ( $c eq ']' ) {
push @outdata, $curdata;
$curdata = undef;
$state = 'await_start1';
}
else { $curdata .= ']]'.$c; $state='in_data' }
}
else { die "internal error: bad state $state" }
}
return \@outdata;
}