next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Llamadas a subreglas desmemoriadas Sup: Análisis Sintáctico con Regexp::Grammars Ant: Listas Err: Si hallas una errata ...

Subsecciones


Pseudo sub-reglas

Subpatrones

Aliases can also be given to standard Perl subpatterns, as well as to code blocks within a regex. The syntax for subpatterns is:

    <ALIAS= (SUBPATTERN) >

In other words, the syntax is exactly like an aliased subrule call, except that the rule name is replaced with a set of parentheses containing the subpattern. Any parentheses-capturing or non-capturing-will do.

The effect of aliasing a standard subpattern is to cause whatever that subpattern matches to be saved in the result-hash, using the alias as its key. For example:

    <rule: file_command>

        <cmd=(mv|cp|ln)>  <from=file>  <to=file>

Here, the <cmd=(mv|cp|ln)> is treated exactly like a regular (mv|cp|ln), but whatever substring it matches is saved in the result-hash under the key 'cmd'.
Sigue un ejemplo:
pl@nereida:~/Lregexpgrammars/demo$ cat -n subpattern.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
 9      qr{
10          <file_command>
11
12          <rule: file_command>
13
14          <cmd=(mv|cp|ln)>  <from=([\w./]+)>  <to=([\w./]+)>
15
16      }x;
17  };
18
19  while (my $input = <>) {
20      while ($input =~ m{$rbb}g) {
21          say("matches: <$&>");
22          say Dumper \%/;
23      }
24  }
y una ejecución:
pl@nereida:~/Lregexpgrammars/demo$ perl5.10.1 subpattern.pl
mv a b
matches: <mv a b>
$VAR1 = {
          '' => 'mv a b',
          'file_command' => {
                              '' => 'mv a b',
                              'to' => 'b',
                              'cmd' => 'mv',
                              'from' => 'a'
                            }
        };

cp c d
matches: <cp c d>
$VAR1 = {
          '' => 'cp c d',
          'file_command' => {
                              '' => 'cp c d',
                              'to' => 'd',
                              'cmd' => 'cp',
                              'from' => 'c'
                            }
        }

Bloques de código

The syntax for aliasing code blocks is:

    <ALIAS= (?{ your($code->here) }) >

Note, however, that the code block must be specified in the standard Perl 5.10 regex notation: (?{...}). A common mistake is to write:

    <ALIAS= { your($code->here } >

instead, which will attempt to interpolate $code before the regex is even compiled, as such variables are only protected from interpolation inside a (?{...}).

When correctly specified, this construct executes the code in the block and saves the result of that execution in the result-hash, using the alias as its key. Aliased code blocks are useful for adding semantic information based on which branch of a rule is executed. For example, consider the copy_cmd alternatives shown earlier:

    <rule: copy_cmd>
        copy <from=file>        <to=file>
      | dup    <to=file>  as  <from=file>
      |      <from=file>  ->    <to=file>
      |        <to=file>  <-  <from=file>

Using aliased code blocks, you could add an extra field to the result- hash to describe which form of the command was detected, like so:

    <rule: copy_cmd>
        copy <from=file>        <to=file>  <type=(?{ 'std' })> 
      | dup    <to=file>  as  <from=file>  <type=(?{ 'rev' })> 
      |      <from=file>  ->    <to=file>  <type=(?{ 'fwd' })> 
      |        <to=file>  <-  <from=file>  <type=(?{ 'bwd' })>

Now, if the rule matched, the result-hash would contain something like:

    copy_cmd => {
        from => 'oldfile',
          to => 'newfile',
        type => 'fwd',
    }

El siguiente ejemplo ilustra lo dicho en la documentación. En la línea 15 hemos introducido una regla para el control de errores3.8:

pl@nereida:~/Lregexpgrammars/demo$ cat -n aliasedcodeblock2.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>) <type=(?{ 'std' })>
13          |   <from=file> ->   <to=file> <type=(?{ 'fwd' })>
14          |   <to=file>   <- <from=file> <type=(?{ 'bwd' })>
15          |   .+ (?{ die "Syntax error!\n" })
16
17        <token: file> [\w./\\]+
18      }x;
19  };
20
21  while (my $input = <>) {
22      while ($input =~ m{$rbb}g) {
23          say("matches: <$&>");
24          say Dumper \%/;
25      }
26  }

La ejecución muestra el comportamiento del programa con tres entradas válidas y una errónea:

pl@nereida:~/Lregexpgrammars/demo$ perl5.10.1 aliasedcodeblock2.pl
copy a b
matches: <copy a b
>
$VAR1 = {
          '' => 'copy a b
',
          'copy_cmd' => {
                          '' => 'copy a b
',
                          'to' => 'b',
                          'from' => 'a',
                          'type' => 'std'
                        }
        };

b <- a
matches: <b <- a
>
$VAR1 = {
          '' => 'b <- a
',
          'copy_cmd' => {
                          '' => 'b <- a
',
                          'to' => 'b',
                          'from' => 'a',
                          'type' => 'bwd'
                        }
        };

a -> b
matches: <a -> b
>
$VAR1 = {
          '' => 'a -> b
',
          'copy_cmd' => {
                          '' => 'a -> b
',
                          'to' => 'b',
                          'from' => 'a',
                          'type' => 'fwd'
                        }
        };

cp a b
Syntax error!

Pseudo subreglas y depuración

Note that, in addition to the semantics described above, aliased subpatterns and code blocks also become visible to Regexp::Grammars integrated debugger (see Debugging).


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Llamadas a subreglas desmemoriadas Sup: Análisis Sintáctico con Regexp::Grammars Ant: Listas Err: Si hallas una errata ...
Casiano Rodríguez León
2013-03-05