next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Usando Language::AttributeGrammars con Parse::Eyapp Sup: Análisis Semántico con Parse::Eyapp Ant: Definición Dirigida por la Err: Si hallas una errata ...


El módulo Language::AttributeGrammar

El módulo Language::AttributeGrammar de Luke Palmer permite experimentar en Perl con una variante de las gramáticas atribuidas.

Ejemplo Simple

Language::AttributeGrammar provee un constructor new que recibe la cadena describiendo la gramática atribuída y un método apply que recibe como argumentos el árbol AST y el atributo a evaluar. Language::AttributeGrammar toma como entrada un AST en vez de una descripción textual (línea 36).

nereida:~/src/perl/attributegrammar/Language-AttributeGrammar-0.08/examples> cat -n atg.pl
 1  #!/usr/bin/perl -w
 2  use strict;
 3  use Language::AttributeGrammar;
 4  use Data::Dumper;
 5
 6  my $grammar = new Language::AttributeGrammar <<'EOG';
 7
 8  # find the minimum from the leaves up
 9  Leaf: $/.min = { $<value> }
10  Branch: $/.min = {
11      $<left>.min <= $<right>.min ? $<left>.min : $<right>.min;
12  }
13
14  # propagate the global minimum downward
15  ROOT:   $/.gmin       = { $/.min }
16  Branch: $<left>.gmin  = { $/.gmin }
17  Branch: $<right>.gmin = { $/.gmin }
18
19  # reconstruct the minimized result
20  Leaf:   $/.result  = { bless { value => $/.gmin } => 'Leaf' }
21  Branch: $/.result  = { bless { left  => $<left>.result,
22                                 right => $<right>.result } => 'Branch' }
23
24  EOG
25
26  sub Leaf   { bless { value => $_[0] } => 'Leaf' }
27  sub Branch { bless { left => $_[0], right => $_[1] } => 'Branch' }
28
29  my $tree = Branch(
30              Branch(Leaf(2), Leaf(3)),
31              Branch(Leaf(1), Branch(Leaf(5), Leaf(9))));
32  my $result = Branch(
33              Branch(Leaf(1), Leaf(1)),
34              Branch(Leaf(1), Branch(Leaf(1), Leaf(1))));
35
36  my $t = $grammar->apply($tree, 'result');
37
38  $Data::Dumper::Indent = 1;
39  print Dumper($t);
El objeto representando a la gramática atribuída es creado mediante la llamada a Language::AttributeGrammar::new en la línea 6. La gramática es una secuencia de reglas semánticas. Cada regla semántica tiene la forma:
nodetype1 : $/.attr_1        = { CÓDIGO PERL($<hijo_i>.attr_k )}
          | $<hijo_1>.attr_2 = { CÓDIGO PERL($<hijo_i>.attr_k, $/.attr_s )}
          | $<hijo_2>.attr_3 = { CÓDIGO PERL }
          ....
nodetype2 : $/.attr_1        = { CÓDIGO PERL($<hijo_i>.attr_k )}
          | $<hijo_1>.attr_2 = { CÓDIGO PERL($<hijo_i>.attr_k, $/.attr_s )}
          | $<hijo_2>.attr_3 = { CÓDIGO PERL }
          ....

Notaciones Especiales

Dentro de la especificación de la gramática es posible hacer uso de las notaciones especiales:

La llamada al método $grammar->apply($tree, 'result') en la línea 36 dispara la computación de las reglas para el cálculo del atributo result sobre el árbol $tree.

Cuando ejecutamos el programa obtenemos la salida:

nereida:~/src/perl/attributegrammar/Language-AttributeGrammar-0.08/examples> atg.pl
$VAR1 = bless( {
  'left' => bless( {
    'left' => bless( { 'value' => 1 }, 'Leaf' ),
    'right' => bless( { 'value' => 1 }, 'Leaf' )
  }, 'Branch' ),
  'right' => bless( {
    'left' => bless( { 'value' => 1 }, 'Leaf' ),
    'right' => bless( {
      'left' => bless( { 'value' => 1 }, 'Leaf' ),
      'right' => bless( { 'value' => 1 }, 'Leaf' )
    }, 'Branch' )
  }, 'Branch' )
}, 'Branch' );

Descripción del Lenguaje de Language::AttributeGrammar

Sigue una descripción en estilo Parse::Eyapp de la gramática aceptada por Language::AttributeGrammar :

grammar: rule *

rule: nodetype ':' (target '.' attr '=' '{' BLOQUE DE CÓDIGO PERL '}') <* '|'>

target: self | child | accesscode
Las variables nodetype, attr, self, child y accesscode viene definidas por las siguientes expresiones regulares:

nodetype:    /(::)?\w+(::\w+)*/ # identificador Perl del tipo de nodo (PLUS, MINUS, etc.)
attr:    /\w+/      # identificador del atributo
self:    '$/'       # Se refiere al nodo visitado
child:   /\$<\w+>/  # Hijo del nodo visitado
accesscode: /`.*?`/ # Código explícito de acceso al hijo del nodo



Subsecciones
next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Usando Language::AttributeGrammars con Parse::Eyapp Sup: Análisis Semántico con Parse::Eyapp Ant: Definición Dirigida por la Err: Si hallas una errata ...
Casiano Rodríguez León
2012-05-22