# load source code into $_ while( m{['"{}]|//|/*|\bclass\s+}g ) { my $c = substr( $_, pos($_)-1, 1 ); if( "'" eq $c ) { m{\G(?:[^\\']+|\\.)*'}gc or fail( \$_, "Unclosed char" ); } elsif( '"' eq $c ) { m{\G(?:[^\\"]+|\\.)*"}gc or fail( \$_, "Unclosed string" ); } elsif( '/' eq $c ) { m{\G[^\n]*}gc; } elsif( '*' eq $c ) { m{*/}gc or fail( \$_, "Unclosed comment" ); } elsif( '{' eq $c ) { $nest++; } elsif( '}' eq $c ) { $nest--; } elsif( 's' eq $c ) { my $p = pos(); m{\G\w+}gc or fail( \$_, "'class' not followed by ID" ); my $name = substr( $_, $p, pos()-$p ); if( m[\G\s*:\s*(?:\w+\s+)?(\w+)\s+{]gc ) { my $ancestor = $1; $nest++; } elsif( ! m[\s*{}gc ) { fail( \$_, "No { after 'class $name'" ); } } }