Spec-Zone .ru
спецификации, руководства, описания, API
Spec-Zone .ru
спецификации, руководства, описания, API
Библиотека разработчика Mac Разработчик
Поиск

 

Эта страница руководства для  версии 10.9 Mac OS X

Если Вы выполняете различную версию  Mac OS X, просматриваете документацию локально:

Читать страницы руководства

Страницы руководства предназначаются как справочник для людей, уже понимающих технологию.

  • Чтобы изучить, как руководство организовано или узнать о синтаксисе команды, прочитайте страницу руководства для страниц справочника (5).

  • Для получения дополнительной информации об этой технологии, ищите другую документацию в Библиотеке Разработчика Apple.

  • Для получения общей информации о записи сценариев оболочки, считайте Shell, Пишущий сценарий Учебника для начинающих.



Parse::Eyapp::defaultactionsintro(3) User Contributed Perl DocumentationParse::Eyapp::defaultactionsintro(3)



NAME
       Parse::Eyapp::defaultactionsintro - Introduction to Default Actions and Grammar Reuse

Introduction
       The examples used in this tutorial can be found in the directory "examples/recycle" accompanying this
       distribution

Default Actions
   Default actions
       When no action is specified both "yapp" and "eyapp" implicitly insert the semantic action "{ $_[1]
       }".  In "Parse::Eyapp" you can modify such behavior using the "%defaultaction { Perl code }"
       directive. The "{ Perl code }" clause that follows the %defaultaction directive is executed when
       reducing by any production for which no explicit action was specified.

       Translator from Infix to Postfix

       See the example in "examples/eyapplanguageref/Postfix.eyp"  that translates an infix expression like
       "a=b*-3" into a postfix expression like "a b 3 NEG * = ":

         Parse-Eyapp/examples/eyapplanguageref$ cat -n Postfix.eyp
            1  # File Postfix.eyp
            2  %right  '='
            3  %left   '-' '+'
            4  %left   '*' '/'
            5  %left   NEG
            6
            7  %defaultaction { return  "$left $right $op"; }
            8
            9  %%
           10  line: $exp  { print "$exp\n" }
           11  ;
           12
           13  exp:        $NUM  { $NUM }
           14          |   $VAR  { $VAR }
           15          |   VAR.left '='.op exp.right
           16          |   exp.left '+'.op exp.right
           17          |   exp.left '-'.op exp.right
           18          |   exp.left '*'.op exp.right
           19          |   exp.left '/'.op exp.right
           20          |   '-' $exp %prec NEG { "$exp NEG" }
           21          |   '(' $exp ')' { $exp }
           22  ;
           23
           24  %%
           25
           26  sub _Error {
           27    my($token)=$_[0]->YYCurval;
           28    my($what)= $token ? "input: '$token'" : "end of input";
           29    my @expected = $_[0]->YYExpect();
           30
           31    local $" = ', ';
           32    die "Syntax error near $what. Expected one of these tokens: @expected\n";
           33  }
           34
           35  my $x;
           36
           37  sub _Lexer {
           38    my($parser)=shift;
           39
           40    for ($x) {
           41      s/^\s+//;
           42      $_ eq '' and return('',undef);
           43
           44      s/^([0-9]+(?:\.[0-9]+)?)//   and return('NUM',$1);
           45      s/^([A-Za-z][A-Za-z0-9_]*)// and return('VAR',$1);
           46      s/^(.)//s                    and return($1,$1);
           47    }
           48  }
           49
           50  sub Run {
           51    my($self)=shift;
           52    my $debug = shift @ARGV;
           53    $debug = 0x1F if $debug;
           54    print "Infix to postfix translator. Write an arithmetic expression: ";
           55    $x = <STDIN>;
           56    $self->YYParse(
           57      yylex => \&_Lexer,
           58      yyerror => \&_Error,
           59      yydebug => $debug,
           60    );
           61  }
           62
           63   # Modulino
           64   __PACKAGE__->new()->Run unless caller();

       The file containing the "Eyapp" program must be compiled with "eyapp":

        Parse-Eyapp/examples/eyapplanguageref$ eyapp Postfix.eyp

       Next, you have to write a client program:

         Parse-Eyapp/examples/eyapplanguageref$ cat -n usepostfix.pl
            1  #!/usr/bin/perl -w
            2  use strict;
            3  use Postfix;
            4
            5  my $parser = new Postfix();
            6  $parser->Run;

       Now we can run the client program:

        Parse-Eyapp/examples/eyapplanguageref$ usepostfix.pl
        Infix to postfix translator. Write an arithmetic expression: -(2*a-b*-3)
        2 a * b 3 NEG * - NEG

       An alternative is to use the generated module as a modulino, compiling the grammar using option "-b":

         Parse-Eyapp/examples/eyapplanguageref$ eyapp -b '' Postfix.eyp

       This way, we can directly use the modulo as a script:

         Parse-Eyapp/examples/eyapplanguageref$ ./Postfix.pm
         Infix to postfix translator. Write an arithmetic expression: 2*3+b
         2 3 * b +

       Default Actions, %name and "YYName"

       In "eyapp" each production rule has a name.  The name of a rule can be explicitly given by the
       programmer using the %name directive. For example, in the piece of code that follows the name
       "ASSIGN" is given to the rule "exp: VAR '=' exp".

       When no explicit name is given the rule has an implicit name.  The implicit name of a rule is shaped
       by concatenating the name of the syntactic variable on its left, an underscore and the ordinal number
       of the production rule "Lhs_#" as it appears in the ".output" file.  Avoid giving names matching such
       pattern to production rules.  The patterns "/${lhs}_\d+$/" where "${lhs}" is the name of the
       syntactic variable are reserved for internal use by "eyapp".

         pl@nereida:~/LEyapp/examples$ cat -n Lhs.eyp
          1  # Lhs.eyp
          2
          3  %right  '='
          4  %left   '-' '+'
          5  %left   '*' '/'
          6  %left   NEG
          7
          8  %defaultaction {
          9    my $self = shift;
         10    my $name = $self->YYName();
         11    bless { children => [ grep {ref($_)} @_] }, $name;
         12  }
         13
         14  %%
         15  input:
         16              /* empty */
         17                { [] }
         18          |   input line
         19                {
         20                  push @{$_[1]}, $_[2] if defined($_[2]);
         21                  $_[1]
         22                }
         23  ;
         24
         25  line:     '\n'       { }
         26          | exp '\n'   {  $_[1] }
         27  ;
         28
         29  exp:
         30              NUM   { $_[1] }
         31          |   VAR   { $_[1] }
         32          |   %name ASSIGN
         33              VAR '=' exp
         34          |   %name PLUS
         35              exp '+' exp
         36          |   %name MINUS
         37              exp '-' exp
         38          |   %name TIMES
         39              exp '*' exp
         40          |   %name DIV
         41              exp '/' exp
         42          |   %name UMINUS
         43              '-' exp %prec NEG
         44          |  '(' exp ')'  { $_[2] }
         45  ;

       Inside a semantic action the name of the current rule can be recovered using the method "YYName" of
       the parser object.

       The default action (lines 8-12) computes as attribute of the left hand side a reference to an object
       blessed in the name of the rule.  The object has an attribute "children" which is a reference to the
       list of children of the node.  The call to "grep"

         11    bless { children => [ grep {ref($_)} @_] }, $name;

       excludes children that aren't references. Notice that the lexical analyzer only returns references
       for the "NUM" and "VAR" terminals:

         59  sub _Lexer {
         60      my($parser)=shift;
         61
         62      for ($parser->YYData->{INPUT}) {
         63          s/^[ \t]+//;
         64          return('',undef) unless $_;
         65          s/^([0-9]+(?:\.[0-9]+)?)//
         66                  and return('NUM', bless { attr => $1}, 'NUM');
         67          s/^([A-Za-z][A-Za-z0-9_]*)//
         68                  and return('VAR',bless {attr => $1}, 'VAR');
         69          s/^(.)//s
         70                  and return($1, $1);
         71      }
         72      return('',undef);
         73  }

       follows the client program:

         pl@nereida:~/LEyapp/examples$ cat -n uselhs.pl
              1  #!/usr/bin/perl -w
              2  use Lhs;
              3  use Data::Dumper;
              4
              5  $parser = new Lhs();
              6  my $tree = $parser->Run;
              7  $Data::Dumper::Indent = 1;
              8  if (defined($tree)) { print Dumper($tree); }
              9  else { print "Cadena no vA~Xlida\n"; }

       When executed with input "a=(2+3)*b" the parser produces the following tree:

         ASSIGN(TIMES(PLUS(NUM[2],NUM[3]), VAR[b]))

       See the result of an execution:

         pl@nereida:~/LEyapp/examples$ uselhs.pl
         a=(2+3)*b
         $VAR1 = [
           bless( {
             'children' => [
               bless( { 'attr' => 'a' }, 'VAR' ),
               bless( {
                 'children' => [
                   bless( {
                     'children' => [
                       bless( { 'attr' => '2' }, 'NUM' ),
                       bless( { 'attr' => '3' }, 'NUM' )
                     ]
                   }, 'PLUS' ),
                   bless( { 'attr' => 'b' }, 'VAR' )
                 ]
               }, 'TIMES' )
             ]
           }, 'ASSIGN' )
         ];

       The name of a production rule can be changed at execution time.  See the following example:

         29  exp:
         30              NUM   { $_[1] }
         31          |   VAR   { $_[1] }
         32          |   %name ASSIGN
         33              VAR '=' exp
         34          |   %name PLUS
         35              exp '+' exp
         36          |   %name MINUS
         37              exp '-' exp
         38                {
         39                  my $self = shift;
         40                  $self->YYName('SUBTRACT'); # rename it
         41                  $self->YYBuildAST(@_); # build the node
         42                }
         43          |   %name TIMES
         44              exp '*' exp
         45          |   %name DIV
         46              exp '/' exp
         47          |   %name UMINUS
         48              '-' exp %prec NEG
         49          |  '(' exp ')'  { $_[2] }
         50  ;

       When the client program is executed we can see the presence of the "SUBTRACT" nodes:

         pl@nereida:~/LEyapp/examples$ useyynamedynamic.pl
         2-b
         $VAR1 = [
           bless( {
             'children' => [
               bless( {
                 'attr' => '2'
               }, 'NUM' ),
               bless( {
                 'attr' => 'b'
               }, 'VAR' )
             ]
           }, 'SUBTRACT' )
         ];

Grammar Reuse
       Terence Parr in his talk "Reuse of Grammars with Embedded Semantic Actions" (see
       <http://www.cs.vu.nl/icpc2008/docs/Parr.pdf>) explains the problem:

        "Because many applications deal with the same language, the reuse of a common
       syntax specification with different semantics provides a number of advantages.
       While the advantages are obvious, the mechanism for grammar reuse is not so
       clear.  To go beyond syntax checking, grammars must have some way to specify
       the translation or interpretation logic (the semantics). Unfortunately, the act
       of specifying the semantics can lock a grammar into one specific application
       since the grammar is often modified to suit (e.g., programmers often want to
       embed unrestricted semantic actions)."

       The incoming sections deal with different solutions to the problem.

   An Action Method for each Production
       Default actions provide a way to write reusable grammars.  Here is one solution:

         pl@europa:~/LEyapp/examples/recycle$ cat -n Noactions.eyp
            1  %left   '+'
            2  %left   '*'
            3
            4  %defaultaction {
            5    my $self = shift;
            6
            7    my $class = $self->YYPrefix;
            8    $class .=  $self->YYName;
            9
           10    $class->action(@_);
           11  }
           12
           13  %%
           14  exp:        %name NUM
           15                NUM
           16          |   %name PLUS
           17                exp '+' exp
           18          |   %name TIMES
           19                exp '*' exp
           20          |   '(' exp ')'
           21                { $_[2] }
           22  ;
           23
           24  %%
           25
           26  sub _Error {
           27    my($token)=$_[0]->YYCurval;
           28    my($what)= $token ? "input: '$token'" : "end of input";
           29    my @expected = $_[0]->YYExpect();
           30
           31    local $" = ', ';
           32    die "Syntax error near $what. Expected one of these tokens: @expected\n";
           33  }
           34
           35
           36  my $x = '';
           37
           38  sub _Lexer {
           39    my($parser)=shift;
           40
           41    for ($x) {
           42      s/^\s+//;
           43      $_ eq '' and return('',undef);
           44
           45      s/^([0-9]+(?:\.[0-9]+)?)//   and return('NUM',$1);
           46      s/^([A-Za-z][A-Za-z0-9_]*)// and return('VAR',$1);
           47      s/^(.)//s                    and return($1,$1);
           48    }
           49  }
           50
           51  sub Run {
           52    my($self)=shift;
           53    $x = shift;
           54    my $debug = shift;
           55
           56    $self->YYParse(
           57      yylex    => \&_Lexer,
           58      yyerror  => \&_Error,
           59      yydebug  => $debug,
           60    );
           61  }

       This grammar is reused by the following program to implement a calculator: and a translator from
       infix to postfix:

         pl@europa:~/LEyapp/examples/recycle$ cat -n calcu_and_post.pl
            1  #!/usr/bin/perl
            2  use warnings;
            3  use Noactions;
            4
            5  sub Calc::NUM::action {
            6    return $_[1];
            7  }
            8
            9  sub Calc::PLUS::action {
           10    $_[1]+$_[3];
           11  }
           12
           13  sub Calc::TIMES::action {
           14    $_[1]*$_[3];
           15  }
           16
           17  sub Post::NUM::action {
           18    return $_[1];
           19  }
           20
           21  sub Post::PLUS::action {
           22    "$_[1] $_[3] +";
           23  }
           24
           25  sub Post::TIMES::action {
           26    "$_[1] $_[3] *";
           27  }
           28
           29  my $debug = shift || 0;
           30  my $pparser = Noactions->new( yyprefix => 'Post::');
           31  print "Write an expression: ";
           32  my $x = <STDIN>;
           33  my $t = $pparser->Run($x, $debug);
           34
           35  print "$t\n";
           36
           37  my $cparser = Noactions->new(yyprefix => 'Calc::');
           38  my $e = $cparser->Run($x, $debug);
           39
           40  print "$e\n";

   Reusing Grammars Using Inheritance
       An method to reuse a grammar is via inheritance.  The client inherits the generated parser module and
       expands it with methods that inherit or overwrite the actions.  Here is an example. Initially we have
       this Eyapp grammar:

         pl@europa:~/LEyapp/examples/recycle$ cat -n NoacInh.eyp
            1  %left   '+'
            2  %left   '*'
            3
            4  %defaultaction {
            5    my $self = shift;
            6
            7    my $action = $self->YYName;
            8
            9    $self->$action(@_);
           10  }
           11
           12  %%
           13  exp:        %name NUM
           14                NUM
           15          |   %name PLUS
           16                exp '+' exp
           17          |   %name TIMES
           18                exp '*' exp
           19          |   '(' exp ')'
           20                { $_[2] }
           21  ;
           22
           23  %%
           24
           25  sub _Error {
           26    my($token)=$_[0]->YYCurval;
           27    my($what)= $token ? "input: '$token'" : "end of input";
           28    my @expected = $_[0]->YYExpect();
           29
           30    local $" = ', ';
           31    die "Syntax error near $what. Expected one of these tokens: @expected\n";
           32  }
           33
           34
           35  my $x = '';
           36
           37  sub _Lexer {
           38    my($parser)=shift;
           39
           40    for ($x) {
           41      s/^\s+//;
           42      $_ eq '' and return('',undef);
           43
           44      s/^([0-9]+(?:\.[0-9]+)?)//   and return('NUM',$1);
           45      s/^([A-Za-z][A-Za-z0-9_]*)// and return('VAR',$1);
           46      s/^(.)//s                    and return($1,$1);
           47    }
           48  }
           49
           50  sub Run {
           51    my($self)=shift;
           52    $x = shift;
           53    my $debug = shift;
           54
           55    $self->YYParse(
           56      yylex => \&_Lexer,
           57      yyerror => \&_Error,
           58      yydebug => $debug,
           59    );
           60  }

       The following program defines two classes: "CalcActions" that implements the actions for the
       calculator and package "PostActions" that implements the actions for the infix to postfix
       translation. This way we have an example that reuses the former grammar twice:

         pl@europa:~/LEyapp/examples/recycle$ cat -n icalcu_and_ipost.pl
            1  #!/usr/bin/perl -w
            2  package CalcActions;
            3  use strict;
            4  use base qw{NoacInh};
            5
            6  sub NUM {
            7    return $_[1];
            8  }
            9
           10  sub PLUS {
           11    $_[1]+$_[3];
           12  }
           13
           14  sub TIMES {
           15    $_[1]*$_[3];
           16  }
           17
           18  package PostActions;
           19  use strict;
           20  use base qw{NoacInh};
           21
           22  sub NUM {
           23    return $_[1];
           24  }
           25
           26  sub PLUS {
           27    "$_[1] $_[3] +";
           28  }
           29
           30  sub TIMES {
           31    "$_[1] $_[3] *";
           32  }
           33
           34  package main;
           35  use strict;
           36
           37  my $calcparser = CalcActions->new();
           38  print "Write an expression: ";
           39  my $x = <STDIN>;
           40  my $e = $calcparser->Run($x);
           41
           42  print "$e\n";
           43
           44  my $postparser = PostActions->new();
           45  my $p = $postparser->Run($x);
           46
           47  print "$p\n";

       The subroutine used as default action in "NoacInh.eyp" is so useful that is packed as the
       Parse::Eyapp::Driver method "YYDelegateaction".

       See files "examples/recycle/NoacYYDelegateaction.eyp" and
       "examples/recycle/icalcu_and_ipost_yydel.pl" for an example of use of "YYDelegateaction".

   Reusing Grammars by Dynamic Substitution of Semantic Actions
       The methods "YYSetaction" and "YYAction" of the parser object provide a way to selectively substitute
       some actions of a given grammar.  Let us consider once more a postfix to infix translator:

         pl@europa:~/LEyapp/examples/recycle$ cat -n PostfixWithActions.eyp
            1  # File PostfixWithActions.eyp
            2  %right  '='
            3  %left   '-' '+'
            4  %left   '*' '/'
            5  %left   NEG
            6
            7  %%
            8  line: $exp  { print "$exp\n" }
            9  ;
           10
           11  exp:        $NUM
           12                  { $NUM }
           13          |   $VAR
           14                  { $VAR }
           15          |   %name ASSIGN
           16                VAR.left '='exp.right
           17                  { "$_[3] &$_[1] ASSIGN"; }
           18          |   %name PLUS
           19                exp.left '+'exp.right
           20                  { "$_[1] $_[3] PLUS"; }
           21          |   %name MINUS
           22                exp.left '-'exp.right
           23                  { "$_[1] $_[3] MINUS"; }
           24          |   %name TIMES
           25                exp.left '*'exp.right
           26                  { "$_[1] $_[3] TIMES"; }
           27          |   %name DIV
           28                exp.left '/'exp.right
           29                  { "$_[1] $_[3] DIV"; }
           30          |   %name NEG '-' $exp %prec NEG
           31                  { "$exp NEG" }
           32          |   '(' $exp ')'
           33                  { $exp }
           34  ;
           35
           36  %%
           37
           38  sub _Error {
           39    my($token)=$_[0]->YYCurval;
           40    my($what)= $token ? "input: '$token'" : "end of input";
           41    my @expected = $_[0]->YYExpect();
           42
           43    local $" = ', ';
           44    die "Syntax error near $what. Expected one of these tokens: @expected\n";
           45  }
           46
           47  my $x;
           48
           49  sub _Lexer {
           50    my($parser)=shift;
           51
           52    for ($x) {
           53      s/^\s+//;
           54      $_ eq '' and return('',undef);
           55
           56      s/^([0-9]+(?:\.[0-9]+)?)//   and return('NUM',$1);
           57      s/^([A-Za-z][A-Za-z0-9_]*)// and return('VAR',$1);
           58      s/^(.)//s                    and return($1,$1);
           59    }
           60  }
           61
           62  sub Run {
           63    my($self)=shift;
           64    $x = shift;
           65    $self->YYParse( yylex => \&_Lexer, yyerror => \&_Error,
           66      #yydebug => 0xFF
           67    );
           68  }

       The program "rewritepostfixwithactions.pl" uses the former grammar to translate infix expressions to
       postfix expressions.  It also implements a calculator reusing the grammar in
       "PostfixWithActions.eyp". It does so using the "YYSetaction" method.  The semantic actions for the
       productions named

        ASSIGN

        PLUS

        TIMES

        DIV

        NEG

       are selectively substituted by the appropriate actions, while the other semantic actions remain
       unchanged:

         pl@europa:~/LEyapp/examples/recycle$ cat -n rewritepostfixwithactions.pl
            1  #!/usr/bin/perl
            2  use warnings;
            3  use PostfixWithActions;
            4
            5  my $debug = shift || 0;
            6  my $pparser = PostfixWithActions->new();
            7  print "Write an expression: ";
            8  my $x = <STDIN>;
            9
           10  # First, trasnlate to postfix ...
           11  $pparser->Run($x, $debug);
           12
           13  # And then selectively substitute
           14  # some semantic actions
           15  # to obtain an infix calculator ...
           16  my %s;            # symbol table
           17  $pparser->YYSetaction(
           18    ASSIGN => sub { $s{$_[1]} = $_[3] },
           19    PLUS   => sub { $_[1] + $_[3] },
           20    TIMES  => sub { $_[1] * $_[3] },
           21    DIV    => sub { $_[1] / $_[3] },
           22    NEG    => sub { -$_[2] },
           23  );
           24
           25  $pparser->Run($x, $debug);

       When running this program the output is:

         examples/recycle$ ./rewritepostfixwithactions.pl
         Write an expression: 2*3+4
         2 3 TIMES 4 PLUS
         10
         examples/recycle$ rewritepostfixwithactions.pl
         Write an expression: a = 2*(b = 3+5)
         2 3 5 PLUS &b ASSIGN TIMES &a ASSIGN
         16

SEE ALSO
          The project home is at http://code.google.com/p/parse-eyapp/ <http://code .google.com/p/parse-
           eyapp/>.  Use a subversion client to anonymously check out the latest project source code:

              svn checkout http://parse-eyapp.googlecode.com/svn/trunk/ parse-eyapp-read-only

          The tutorial Parsing Strings and Trees with "Parse::Eyapp" (An Introduction to Compiler
           Construction in seven pages) in <http://nereida.deioc.ull.es/~pl/eyapsimple/>

          Parse::Eyapp, Parse::Eyapp::eyapplanguageref, Parse::Eyapp::debuggingtut,
           Parse::Eyapp::defaultactionsintro, Parse::Eyapp::translationschemestut, Parse::Eyapp::Driver,
           Parse::Eyapp::Node, Parse::Eyapp::YATW, Parse::Eyapp::Treeregexp, Parse::Eyapp::Scope,
           Parse::Eyapp::Base, Parse::Eyapp::datagenerationtut

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/languageintro.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/debuggingtut.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/eyapplanguageref.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/Treeregexp.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/Node.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/YATW.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/Eyapp.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/Base.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/translationschemestut.pdf>

          The pdf file in <http://nereida.deioc.ull.es/~pl/perlexamples/treematchingtut.pdf>

          perldoc eyapp,

          perldoc treereg,

          perldoc vgg,

          The Syntax Highlight file for vim at <http://www.vim.org/scripts/script.php?script_id=2453> and
           <http://nereida.deioc.ull.es/~vim/>

          Analisis Lexico y Sintactico, (Notes for a course in compiler construction) by  Casiano
           Rodriguez-Leon.  Available at  <http://nereida.deioc.ull.es/~pl/perlexamples/> Is the more
           complete and reliable source for Parse::Eyapp. However is in Spanish.

          Parse::Yapp,

          Man pages of yacc(1) and bison(1), <http://www.delorie.com/gnu/docs/bison/bison.html>

          Language::AttributeGrammar

          Parse::RecDescent.

          HOP::Parser

          HOP::Lexer

          ocamlyacc tutorial at
           http://plus.kaist.ac.kr/~shoh/ocaml/ocamllex-ocamlyacc/ocamlyacc-tutorial/ocamlyacc-tutorial.html
           <http://plus .kaist.ac.kr / ~ shoh/ocaml/ocamllex-ocamlyacc/ocamlyacc-tutorial/ocamlyacc-
           tutorial.html>

REFERENCES
          The classic Dragon's book Compilers: Principles, Techniques, and Tools by Alfred V. Aho, Ravi
           Sethi and Jeffrey D. Ullman (Addison-Wesley 1986)

          CS2121: The Implementation and Power of Programming Languages (See
           <http://www.cs.man.ac.uk/~pjj>, <http://www.cs.man.ac.uk/~pjj/complang/g2lr.html> and
           <http://www.cs.man.ac.uk/~pjj/cs2121/ho/ho.html>) by Pete Jinks

CONTRIBUTORS
        Hal Finkel <http://www.halssoftware.com/>

        G. Williams <http://kasei.us/>

        Thomas L. Shinnick <http://search.cpan.org/~tshinnic/>

        Frank Leray

AUTHOR
       Casiano Rodriguez-Leon (casiano@ull.es)

ACKNOWLEDGMENTS
       This work has been supported by CEE (FEDER) and the Spanish Ministry of Educacion y Ciencia through
       Plan Nacional I+D+I number TIN2005-08818-C04-04 (ULL::OPLINK project <http://www.oplink.ull.es/>).
       Support from Gobierno de Canarias was through GC02210601 (Grupos Consolidados).  The University of La
       Laguna has also supported my work in many ways and for many years.

       A large percentage of  code is verbatim taken from Parse::Yapp 1.05.  The author of Parse::Yapp is
       Francois Desarmenien.

       I wish to thank Francois Desarmenien for his Parse::Yapp module, to my students at La Laguna and to
       the Perl Community. Thanks to the people who have contributed to improve the module (see
       "CONTRIBUTORS" in Parse::Eyapp).  Thanks to Larry Wall for giving us Perl.  Special thanks to Juana.

LICENCE AND COPYRIGHT
       Copyright (c) 2006-2008 Casiano Rodriguez-Leon (casiano@ull.es). All rights reserved.

       Parse::Yapp copyright is of Francois Desarmenien, all rights reserved. 1998-2001

       These modules are free software; you can redistribute it and/or modify it under the same terms as
       Perl itself. See perlartistic.

       This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
       even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



perl v5.12.5                                     2011-02-16             Parse::Eyapp::defaultactionsintro(3)

Сообщение о проблемах

Способ сообщить о проблеме с этой страницей руководства зависит от типа проблемы:

Ошибки содержания
Ошибки отчета в содержании этой документации к проекту Perl. (См. perlbug (1) для инструкций представления.)
Отчеты об ошибках
Сообщите об ошибках в функциональности описанного инструмента или API к Apple через Генератор отчетов Ошибки и к проекту Perl, использующему perlbug (1).
Форматирование проблем
Отчет, форматирующий ошибки в интерактивной версии этих страниц со ссылками на отзыв ниже.