in reply to Parse C-like define statements

What about forward references? Can you use definitions before they occur? If not, it seems like you just need to do things in one pass instead of two (untested):
. . . my %defines; while(<FILE>) { chomp; if (/^#DEFINE \s+ <(\w+)> \s+ (.*) $/x) { my ($def, $text) = ($1, $2); 1 while $text =~ s/<(\w+)>/$defines{$1}/; $defines{$def} = $text; } } . . .
And I hope you're only calling this once per file. If you pass in the same filename multiple times with different $options, then you should be caching the definition maps in a global variable or a passed-in parameter, like:
sub parseDefines { my ($filename, $option, $defines) = @_; return $defines->{$option} if $defines; $defines = {}; ... }