The reason the alias is not accessible in other rules is because of the
local *a
Local gives a variable a temporary value that last until you exit the current set of curly brackets so
$a = 1;
{
local $a = 2;
print "$a\n";
}
print "$a\n";
prints
2
1
So basically your alias disappears as soon as you exit ruleX.
So the answer is to not use local. This has a downside of course, if you don't use local then the alias will never go away, so you might have to do something funky like emulating localisation.
WARNING: doing this sucks, it's very easy to make a mistake. If I ever saw this in a module, I would have serious doubts about the author!
my $grammar = q{
{our @a, @as}
ruleX: r1 local_a r2 r3 unlocal_a
local_a: {
push(@as, \@a);
*a{ARRAY} = undef;
}
unlocal_a: {
*a{ARRAY} = pop(@as);
}
r2: 'keyword' /[a-z]+/ {
local *a = \@::{$item[2]};
}
r3: 'value' /[a-z]+/ {
print @a;
}
}
What will happen is:
r1 will be matched and executed
local_a will save a ref to the current @a onto the @as stack
r2 will alias something to @a
r3 can now use @a and get the value that r2 put into
finally unlocal_a will put @a back to whatever it was beforehand.
So using the above lets you share aliases between rules of the grammar and it lets you nest those rules too because it makes sure it always saves the previous alias and restores it when you're done. However it is very easy to forget the unlocal_a at the end. Plus it's a lot of work and you have to write 2 rules for every variable you want to use for aliases. So don't do this unless you really really really have to.
As to the second question, I don't really know what you mean. Can you rephrase it. |