Nice work! I wonder why you opt to parse this format specifically instead of the generic lisp format though.
As for the speed, it's actually rather on-par with Data::SExpression, which uses Parse::Yapp. I commented out the dumping and then:
% time perl 11115197.pl archive-contents
% time perl -MFile::Slurper=read_text -MData::SExpression -E'$ds=Data::SExpression->new; ($sexp, $text) = $ds->read(read_text "archive-contents.2");'
archive-contents.2 is just the original file with replaced with ( ), and then the problematic @ atom replaced by "@".
Perl regex or Regexp::Grammars will probably be several times faster.