You want to use a stack.

A stack is an abstract concept in programming. It is basically a list that you can only access from the tail end. You can push things onto the stack, and pop the item on the top off the stack, and you can detect when the stack is empty.

As I said, stacks are an abstract concept; you need a concrete realisation of them. In Perl, that's an array. Perl helpfully provides built-in push and pop functions, and makes it easy to check if an array is empty.

This is the basic technique you want...

my @if_stack; while (<$input>) { if (/$start/) { push @if_stack, $_; next; } if (/$stop/) { die unless @if_stack; pop @if_stack; next; } if (@if_stack) { # got a line which is inside a conditional } else { # got a line which is not inside a conditional print $output $_; } }

In fact, in this case you could get away with using a data structure even simpler than a stack - a counter will do. You simply pretend you've got an imaginary stack, and use a counter that keeps track of how many items are on the stack. Instead of pushing onto the stack, increment the counter; instead of popping, decrement.

my $if_stack; while (<$input>) { if (/$start/) { $if_stack++; next; } if (/$stop/) { die unless $if_stack; $if_stack--; next; } if ($if_stack) { # got a line which is inside a conditional } else { # got a line which is not inside a conditional print $output $_; } }

I maintain that the stack is the better solution because you can, for example, print a dump of the current stack when you detect an error, which can help in identifying where things have gone wrong. That said, if you're crunching though vast quantities of text, the counter will probably perform slightly faster.

perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

In reply to Re: nested #if directive matching matching by tobyink
in thread nested #if directive matching matching by prassi

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.