No siempre el nombre de la regla es el mas apropiado para ser el nombre del resultado:
It is not always convenient to have subrule results stored under the same name as the rule itself. Rule names should be optimized for understanding the behaviour of the parser, whereas result names should be optimized for understanding the structure of the data. Often those two goals are identical, but not always; sometimes rule names need to describe what the data looks like, while result names need to describe what the data means.
For example, sometimes you need to call the same rule twice, to match two syntactically identical components whose positions give then semantically distinct meanings:
<rule: copy_cmd> copy <file> <file>
The problem here is that, if the second call to<file>
succeeds, its result-hash will be stored under the keyfile
, clobbering the data that was returned from the first call to<file>
.
To avoid such problems, Regexp::Grammars
allows you to alias any
subrule call, so that it is still invoked by the original name, but its
result-hash is stored under a different key. The syntax for that is:
<alias=rulename>
. For example:
<rule: copy_cmd> copy <from=file> <to=file>
Here,<rule: file>
is called twice, with the first result-hash being stored under the keyfrom
, and the second result-hash being stored under the keyto
.
Note, however, that the alias before the=
must be a proper identifier (i.e. a letter or underscore, followed by letters, digits, and/or underscores). Aliases that start with an underscore and aliases namedMATCH
have special meaning.
Aliases can also be useful for normalizing data that may appear in different formats and sequences. For example:
<rule: copy_cmd> copy <from=file> <to=file> | dup <to=file> as <from=file> | <from=file> -> <to=file> | <to=file> <- <from=file>
Here, regardless of which order the old and new files are specified, the result-hash always gets:
copy_cmd => { from => 'oldfile', to => 'newfile', }
El siguiente programa ilustra los comentarios de la documentación:
pl@nereida:~/Lregexpgrammars/demo$ cat -n copygrammar.pl 1 use strict; 2 use warnings; 3 use 5.010; 4 use Data::Dumper; 5 6 my $rbb = do { 7 use Regexp::Grammars; 8 qr{ 9 <copy_cmd> 10 11 <rule: copy_cmd> 12 copy <from=file> <to=file> 13 | <from=file> -> <to=file> 14 | <to=file> <- <from=file> 15 16 <token: file> [\w./\\]+ 17 }x; 18 }; 19 20 while (my $input = <>) { 21 while ($input =~ m{$rbb}g) { 22 say("matches: <$&>"); 23 say Dumper \%/; 24 } 25 }Cuando lo ejecutamos obtenemos:
pl@nereida:~/Lregexpgrammars/demo$ perl5.10.1 copygrammar.pl copy a b matches: <copy a b> $VAR1 = { '' => 'copy a b', 'copy_cmd' => { '' => 'copy a b', 'to' => 'b', 'from' => 'a' } }; b <- a matches: <b <- a> $VAR1 = { '' => 'b <- a', 'copy_cmd' => { '' => 'b <- a', 'to' => 'b', 'from' => 'a' } }; a -> b matches: <a -> b> $VAR1 = { '' => 'a -> b', 'copy_cmd' => { '' => 'a -> b', 'to' => 'b', 'from' => 'a' } };