#!/usr/bin/perl use strict; $/=undef; $_=<>; my @stack = (); my $offset = 0; while (( my $i = index( $_, "<" )) >= 0 ) { $offset += $i; $_ = substr( $_, $i ); if ( s{^(<(\w+).*?>)}{} ) { $offset += length( $1 ); push @stack, $2; } elsif( s{^()}{} ) { my $et = $2; if ( $stack[$#stack] eq $et ) { pop @stack; } elsif ( grep( /$et/, @stack )) { print "missing end-tags for:"; while ( @stack and $stack[$#stack] ne $et ) { print " ".pop @stack; } print " at (offset: $offset)\n"; } else { print "missing open-tag for $et (offset: $offset)\n"; } $offset += length( $1 ); } } ### updated: added condition on inner while loop to check for empty stack