Damian Conway wrote:
Alternatively, you could define separate rules for the three cases:
{
state @indents = 0;
rule indent {
^^ $<token>:=(\h*)
{ $<new_indent> = expand_tabs($<token>).chars }
<( $<new_indent> > @indents[-1] )>
{ let @indents = (@indents, $<new_indent>) }
}
rule outdent {
^^ $<token>:=(\h*)
{ $<new_indent> = expand_tabs($<token>).chars }
<( $<new_indent> < @indents[-1] )>
{ pop @indents while @indents && $<new_indent> < @indents[-1];
let @indents = (@indents, $<new_indent>);
}
}
rule samedent { ... }
}
I have a couple of questions about this:
1. It's quite possible that a code-block in a parser could call a
function that reads a different file (e.g. for an "include <file>"
statement). How does the state, @indents, get associated with a
particular match? (Sure, I could do an explicit save/restore; but things
might get harder if I was using coroutines to get concurrent matches to
implement, say, a smart-diff script)
2. How does the outdent rule work in the case where a line does 2
outdents? It looks to me as if I'd only get one match of <outdent>: the
/\h*/ match will advance the match pos, so /^^/ won't match for the
second <outdent> on the same line, which would cause problems if I'm
trying to match up nested blocks.
Dave.