

Veamos un ejemplo:
nereida:~/src/perl/YappWithDefaultAction/examples> cat -n ./alias.pl
1 #!/usr/bin/perl -w
2 use strict;
3 use Parse::Eyapp;
4
5 my $grammar = q{
6 %right '='
7 %left '-' '+'
8 %left '*' '/'
9 %left NEG
!10 %tree bypass alias
11
12 %%
13 line: $exp { $_[1] }
14 ;
15
16 exp:
17 %name NUM
18 $NUM
19 | %name VAR
20 $VAR
21 | %name ASSIGN
22 $VAR '=' $exp
23 | %name PLUS
24 exp.left '+' exp.right
25 | %name MINUS
26 exp.left '-' exp.right
27 | %name TIMES
28 exp.left '*' exp.right
29 | %name DIV
30 exp.left '/' exp.right
31 | %no bypass UMINUS
32 '-' $exp %prec NEG
33 | '(' exp ')' { $_[2] } /* Let us simplify a bit the tree */
34 ;
35
36 %%
37
38 sub _Error {
39 exists $_[0]->YYData->{ERRMSG}
40 and do {
41 print $_[0]->YYData->{ERRMSG};
42 delete $_[0]->YYData->{ERRMSG};
43 return;
44 };
45 print "Syntax error.\n";
46 }
47
48 sub _Lexer {
49 my($parser)=shift;
50
51 $parser->YYData->{INPUT}
52 or $parser->YYData->{INPUT} = <STDIN>
53 or return('',undef);
54
55 $parser->YYData->{INPUT}=~s/^\s+//;
56
57 for ($parser->YYData->{INPUT}) {
58 s/^([0-9]+(?:\.[0-9]+)?)//
59 and return('NUM',$1);
60 s/^([A-Za-z][A-Za-z0-9_]*)//
61 and return('VAR',$1);
62 s/^(.)//s
63 and return($1,$1);
64 }
65 }
66
67 sub Run {
68 my($self)=shift;
69 $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error,
70 #yydebug =>0xFF
71 );
72 }
73 }; # end grammar
74
75
76 Parse::Eyapp->new_grammar(
77 input=>$grammar,
78 classname=>'Alias',
79 firstline =>7,
80 );
81 my $parser = Alias->new();
82 $parser->YYData->{INPUT} = "a = -(2*3+5-1)\n";
83 my $t = $parser->Run;
84 $Parse::Eyapp::Node::INDENT=0;
!85 print $t->VAR->str."\n"; # a
86 print "***************\n";
!87 print $t->exp->exp->left->str."\n"; # 2*3+5
88 print "***************\n";
!89 print $t->exp->exp->right->str."\n"; # 1
Este programa produce la salida:
nereida:~/src/perl/YappWithDefaultAction/examples> ./alias.pl TERMINAL *************** PLUS(TIMES(NUM,NUM),NUM) *************** NUMEl efecto de la opción alias en una regla como:
27 | %name TIMES 28 exp.left '*' exp.rightes crear dos métodos
left y right en la clase TIMES.
El método left permite acceder al hijo izquierdo del nodo en el AST
y el método right al hijo derecho.
El efecto de la opción alias en una regla como:
21 | %name ASSIGN 22 $VAR '=' $expes crear dos métodos en la clase
ASSIGN denominados
VAR y exp los cuales permiten acceder a los
correspondientes hijos de uno nodo ASSIGN.
Los métodos son construidos durante la compilación de la gramática. Por tanto, las modificaciones al AST que el programa introduzca en tiempo de ejecución (por ejemplo la supresión de hijos de ciertos nodos) invalidarán el uso de estos métodos.

