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