Skip to content

Instantly share code, notes, and snippets.

@nlitsme
Created October 30, 2014 00:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nlitsme/c93d466cb3991cf5addf to your computer and use it in GitHub Desktop.
Save nlitsme/c93d466cb3991cf5addf to your computer and use it in GitHub Desktop.
simplify huge c++ template typenames by finding common subexpressions.
# (C) 2003-2007 Willem Jan Hengeveld <itsme@xs4all.nl>
# Web: http://www.xs4all.nl/~itsme/
# http://wiki.xda-developers.com/
#
# attempt to make complicated template symbols more readable
#
# $Id: $
#
use strict;
use warnings;
use Getopt::Long;
my $verbose=0;
GetOptions(
"v" => \$verbose
);
# tool to go from this:
#
# public: __thiscall boost::spirit::binary<struct boost::spirit::alternative<struct boost::spirit::alternative<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t>,struct boost::spirit::parser<struct boost::spirit::alternative<struct boost::spirit::alternative<struct boost::spirit::alternative<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > > >::binary<struct boost::spirit::alternative<struct boost::spirit::alternative<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t>,struct boost::spirit::parser<struct boost::spirit::alternative<struct boost::spirit::alternative<struct boost::spirit::alternative<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > > >(struct boost::spirit::alternative<struct boost::spirit::alternative<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > >,struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> >,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> > > const &,class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t> const &)
#
# to this:
#
# A=class boost::spirit::rule<class boost::spirit::scanner<class std::vector<char,class std::allocator<char> >::const_iterator,struct boost::spirit::scanner_policies<struct boost::spirit::iteration_policy,struct boost::spirit::match_policy,struct boost::spirit::action_policy> >,struct boost::spirit::nil_t,struct boost::spirit::nil_t>
# B=struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::sequence<struct boost::spirit::chlit<char>,class boost::spirit::strlit<char const *> >,A >,A >
# C=struct boost::spirit::alternative<struct boost::spirit::alternative<B,B >,B >
# D=struct boost::spirit::parser<struct boost::spirit::alternative<C,A > >
#
# public: __thiscall boost::spirit::binary<C,A,D >::binary<C,A,D >(C const &,A const &)
#
#
# do this by first replacing [a-z:]+<[^>]+> with new symbol, until everything is a symbol.
# then expand again symbols which occur only once.
#
#
while (<>) {
s/\s+$//;
process($_);
}
sub process {
my $symbol= shift;
# first build symbol table, replacing template<params> with symbol.
my %symtab;
my $n= 0;
while ($symbol =~ /((?:\w+\s+)*[_a-z0-9:]+<[^<>]+>)/) {
my $s= $1;
$symtab{++$n}= $s;
$s =~ s/[*+?{().^\$\\\[]/\\$&/g; # escape regexp chars in $s
$symbol =~ s/$s/ #${n}# /g;
}
# now calc the xrefs, how often is each symbol used.
my %ref;
for my $n (keys %symtab) {
my $s= " #${n}# ";
$ref{$n}= scalar @{[$symbol =~ /($s)/g]};
$ref{$n}+= scalar @{[$_ =~ /($s)/g]} for values %symtab;
}
#printf("#%d# : %d\n", $_, $ref{$_}) for keys %ref;
# if everything has 1 ref, print the result now.
if ($verbose ||!grep { $ref{$_}!=1 } keys %ref) {
printf("#%d#: %s\n", $_, $symtab{$_}) for sort { $a<=>$b } keys %symtab;
printf("%s\n", $symbol);
}
# now reexpand symbols that are only used once.
for my $n (grep { $ref{$_}==1 } keys %ref) {
#printf("%d : %d : %s\n", $n, $count{$n}, $symtab{$n});
my $s= $symtab{$n};
$symtab{$_} =~ s/ #${n}# /$s/g for keys %symtab;
$symbol =~ s/ #${n}# /$s/g;
delete $symtab{$n};
}
# and output the result.
if (keys %symtab) {
printf("#%d#: %s\n", $_, $symtab{$_}) for sort { $a<=>$b } keys %symtab;
printf("%s\n", $symbol);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment