 
 
 
 
 
 
 
 
 
 










 
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 }
          ....
Dentro de la especificación de la gramática es posible hacer uso de las notaciones especiales:
$/ se refiere al nodo que esta siendo visitado
$/.attr se refiere al atributo attr del nodo que esta siendo visitado
$<ident> se refiere al hijo del nodo visitado denominado ident. 
Se asume que el nodo dispone de un método con ese nombre para obtener el hijo.
La notación $<ident>.attr se refiere al atributo attr del hijo ident del nodo visitado.
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' );
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
 
 
 
 
 
 
 
 
 
 
 










