=for state_machine START \n -> {flush} START ws -> START else -> DECL DECL ; -> {flush} START ) -> CLOSE CLOSE { -> {block=1} FUNC else -> DECL FUNC { -> {++block} FUNC } -> { --block ? FUNC : END } END ws -> END \n -> {save} START else -> {save} DECL =end use enum qw( START DECL CLOSE FUNC END ); my $state= START(); my $part= ''; while( $code =~ m{ \G( \n # newline | [^\S\n]+ # horizontal whitespace | [a-z]\w* # identifier | \d+ # digit string | "(?:[^\\"]+|\\[^\n])*" | '(?:[^\\']+|\\[^\n])*' | /\*.*?\*/ # C comment | //[^\n]*\n # C++ comment | [^\w\s] # punctuation mark ) }xsg ) { my $token= $1; if( START() == $state ) { if( $token eq "\n" ) { $token= $part= ''; } elsif( $token =~ /\S/ ) { $state= DECL(); } ... } elsif( END() == $state ) { if( $token =~ /\S/ ) { push @func, $part; $part= ''; ... } } $part .= $token; }