in reply to Clunky parsing problem, looking for simple solution

I don't have a snippet to drop into your compiler, but the general way handle this recursive complexity is with grammar. The following grammar (couresty of the Dragon book) describes the structure of your conditionals, and associates each ELSE with the closest unmatched THEN, eliminating potential ambiguity:
<stmt> := <matched-stmt> | <unmatched-stmt> <matched-stmt> := "IF" <expr> "THEN" <matched-stmt> "ELSE" <matched-s +tmt> | <other-stmt> <unmatched-stmt> := "IF" <expr> "THEN" <stmt> | "IF" <expr> "THEN" <matched-stmt> "ELSE" <unmatch +ed-stmt>
other-stmt is any kind of statement other than a conditional.

Given this grammar, one may create a recursive descent parser that implements this grammar: each nonterminal becomes a subroutine, with stmt at the top of the tree (untested code):
sub stmt { my $buf = shift; if (matched_stmt($buf)) { return 1; } elsif (unmatched_stmt($buf)) { return 1; } return 0; } # etc.
A pity that we don't have Perl6 yet, this grammar could be dropped in straightaway :)

-Mark