deprecated/buildtools/buildsystemtools/lib/Parse/Yapp.pm
author jascui
Tue, 16 Nov 2010 15:56:27 +0800
changeset 683 8e0eb519ef53
parent 655 3f65fd25dfd4
permissions -rw-r--r--
Solve incorrect handling of ExportName=SymbolName@Ordinal syntax
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
655
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     1
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     2
# Module Parse::Yapp.pm.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     3
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     4
# Copyright (c) 1998-2001, Francois Desarmenien, all right reserved.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     5
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     6
# See the Copyright section at the end of the Parse/Yapp.pm pod section
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     7
# for usage and distribution rights.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     8
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     9
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    10
package Parse::Yapp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    11
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    12
use strict;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    13
use vars qw($VERSION @ISA);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    14
@ISA = qw(Parse::Yapp::Output);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    15
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    16
use Parse::Yapp::Output;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    17
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    18
# $VERSION is in Parse/Yapp/Driver.pm
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    19
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    20
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    21
1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    22
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    23
__END__
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    24
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    25
=head1 NAME
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    26
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    27
Parse::Yapp - Perl extension for generating and using LALR parsers. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    28
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    29
=head1 SYNOPSIS
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    30
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    31
  yapp -m MyParser grammar_file.yp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    32
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    33
  ...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    34
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    35
  use MyParser;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    36
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    37
  $parser=new MyParser();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    38
  $value=$parser->YYParse(yylex => \&lexer_sub, yyerror => \&error_sub);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    39
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    40
  $nberr=$parser->YYNberr();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    41
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    42
  $parser->YYData->{DATA}= [ 'Anything', 'You Want' ];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    43
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    44
  $data=$parser->YYData->{DATA}[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    45
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    46
=head1 DESCRIPTION
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    47
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    48
Parse::Yapp (Yet Another Perl Parser compiler) is a collection of modules
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    49
that let you generate and use yacc like thread safe (reentrant) parsers with
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    50
perl object oriented interface.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    51
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    52
The script yapp is a front-end to the Parse::Yapp module and let you
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    53
easily create a Perl OO parser from an input grammar file.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    54
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    55
=head2 The Grammar file
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    56
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    57
=over 4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    58
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    59
=item C<Comments>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    60
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    61
Through all your files, comments are either Perl style, introduced by I<#>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    62
up to the end of line, or C style, enclosed between  I</*> and I<*/>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    63
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    64
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    65
=item C<Tokens and string literals>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    66
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    67
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    68
Through all the grammar files, two kind of symbols may appear:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    69
I<Non-terminal> symbols, called also I<left-hand-side> symbols,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    70
which are the names of your rules, and I<Terminal> symbols, called
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    71
also I<Tokens>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    72
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    73
Tokens are the symbols your lexer function will feed your parser with
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    74
(see below). They are of two flavours: symbolic tokens and string
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    75
literals.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    76
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    77
Non-terminals and symbolic tokens share the same identifier syntax:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    78
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    79
		[A-Za-z][A-Za-z0-9_]*
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    80
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    81
String literals are enclosed in single quotes and can contain almost
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    82
anything. They will be output to your parser file double-quoted, making
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    83
any special character as such. '"', '$' and '@' will be automatically
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    84
quoted with '\', making their writing more natural. On the other hand,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    85
if you need a single quote inside your literal, just quote it with '\'.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    86
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    87
You cannot have a literal I<'error'> in your grammar as it would
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    88
confuse the driver with the I<error> token. Use a symbolic token instead.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    89
In case you inadvertently use it, this will produce a warning telling you
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    90
you should have written it I<error> and will treat it as if it were the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    91
I<error> token, which is certainly NOT what you meant.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    92
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    93
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    94
=item C<Grammar file syntax>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    95
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    96
It is very close to yacc syntax (in fact, I<Parse::Yapp> should compile
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    97
a clean I<yacc> grammar without any modification, whereas the opposite
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    98
is not true).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    99
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   100
This file is divided in three sections, separated by C<%%>:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   101
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   102
	header section
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   103
	%%
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   104
	rules section
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   105
	%%
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   106
	footer section
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   107
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   108
=over 4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   109
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   110
=item B<The Header Section> section may optionally contain:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   111
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   112
=item *
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   113
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   114
One or more code blocks enclosed inside C<%{> and C<%}> just like in
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   115
yacc. They may contain any valid Perl code and will be copied verbatim
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   116
at the very beginning of the parser module. They are not as useful as
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   117
they are in yacc, but you can use them, for example, for global variable
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   118
declarations, though you will notice later that such global variables can
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   119
be avoided to make a reentrant parser module.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   120
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   121
=item *
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   122
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   123
Precedence declarations, introduced by C<%left>, C<%right> and C<%nonassoc>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   124
specifying associativity, followed by the list of tokens or litterals
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   125
having the same precedence and associativity.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   126
The precedence beeing the latter declared will be having the highest level.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   127
(see the yacc or bison manuals for a full explanation of how they work,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   128
as they are implemented exactly the same way in Parse::Yapp)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   129
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   130
=item *
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   131
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   132
C<%start> followed by a rule's left hand side, declaring this rule to
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   133
be the starting rule of your grammar. The default, when C<%start> is not
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   134
used, is the first rule in your grammar section.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   135
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   136
=item *
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   137
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   138
C<%token> followed by a list of symbols, forcing them to be recognized
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   139
as tokens, generating a syntax error if used in the left hand side of
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   140
a rule declaration.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   141
Note that in Parse::Yapp, you I<don't> need to declare tokens as in yacc: any
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   142
symbol not appearing as a left hand side of a rule is considered to be
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   143
a token.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   144
Other yacc declarations or constructs such as C<%type> and C<%union> are
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   145
parsed but (almost) ignored.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   146
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   147
=item *
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   148
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   149
C<%expect> followed by a number, suppress warnings about number of Shift/Reduce
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   150
conflicts when both numbers match, a la bison.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   151
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   152
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   153
=item B<The Rule Section> contains your grammar rules:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   154
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   155
A rule is made of a left-hand-side symbol, followed by a C<':'> and one
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   156
or more right-hand-sides separated by C<'|'> and terminated by a C<';'>:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   157
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   158
    exp:    exp '+' exp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   159
        |   exp '-' exp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   160
        ;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   161
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   162
A right hand side may be empty:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   163
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   164
    input:  #empty
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   165
        |   input line
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   166
        ;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   167
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   168
(if you have more than one empty rhs, Parse::Yapp will issue a warning,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   169
as this is usually a mistake, and you will certainly have a reduce/reduce
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   170
conflict)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   171
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   172
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   173
A rhs may be followed by an optional C<%prec> directive, followed
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   174
by a token, giving the rule an explicit precedence (see yacc manuals
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   175
for its precise meaning) and optionnal semantic action code block (see
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   176
below).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   177
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   178
    exp:   '-' exp %prec NEG { -$_[1] }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   179
        |  exp '+' exp       { $_[1] + $_[3] }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   180
        |  NUM
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   181
        ;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   182
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   183
Note that in Parse::Yapp, a lhs I<cannot> appear more than once as
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   184
a rule name (This differs from yacc).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   185
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   186
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   187
=item C<The footer section>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   188
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   189
may contain any valid Perl code and will be appended at the very end
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   190
of your parser module. Here you can write your lexer, error report
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   191
subs and anything relevant to you parser.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   192
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   193
=item C<Semantic actions>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   194
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   195
Semantic actions are run every time a I<reduction> occurs in the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   196
parsing flow and they must return a semantic value.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   197
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   198
They are (usually, but see below C<In rule actions>) written at
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   199
the very end of the rhs, enclosed with C<{ }>, and are copied verbatim
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   200
to your parser file, inside of the rules table.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   201
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   202
Be aware that matching braces in Perl is much more difficult than
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   203
in C: inside strings they don't need to match. While in C it is
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   204
very easy to detect the beginning of a string construct, or a
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   205
single character, it is much more difficult in Perl, as there
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   206
are so many ways of writing such literals. So there is no check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   207
for that today. If you need a brace in a double-quoted string, just
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   208
quote it (C<\{> or C<\}>). For single-quoted strings, you will need
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   209
to make a comment matching it I<in th right order>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   210
Sorry for the inconvenience.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   211
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   212
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   213
        "{ My string block }".
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   214
        "\{ My other string block \}".
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   215
        qq/ My unmatched brace \} /.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   216
        # Force the match: {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   217
        q/ for my closing brace } /
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   218
        q/ My opening brace { /
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   219
        # must be closed: }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   220
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   221
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   222
All of these constructs should work.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   223
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   224
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   225
In Parse::Yapp, semantic actions are called like normal Perl sub calls,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   226
with their arguments passed in C<@_>, and their semantic value are
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   227
their return values.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   228
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   229
$_[1] to $_[n] are the parameters just as $1 to $n in yacc, while
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   230
$_[0] is the parser object itself.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   231
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   232
Having $_[0] beeing the parser object itself allows you to call
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   233
parser methods. Thats how the yacc macros are implemented:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   234
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   235
	yyerrok is done by calling $_[0]->YYErrok
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   236
	YYERROR is done by calling $_[0]->YYError
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   237
	YYACCEPT is done by calling $_[0]->YYAccept
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   238
	YYABORT is done by calling $_[0]->YYAbort
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   239
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   240
All those methods explicitly return I<undef>, for convenience.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   241
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   242
    YYRECOVERING is done by calling $_[0]->YYRecovering
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   243
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   244
Four useful methods in error recovery sub
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   245
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   246
    $_[0]->YYCurtok
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   247
    $_[0]->YYCurval
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   248
    $_[0]->YYExpect
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   249
    $_[0]->YYLexer
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   250
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   251
return respectivly the current input token that made the parse fail,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   252
its semantic value (both can be used to modify their values too, but
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   253
I<know what you are doing> ! See I<Error reporting routine> section for
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   254
an example), a list which contains the tokens the parser expected when
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   255
the failure occured and a reference to the lexer routine.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   256
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   257
Note that if C<$_[0]-E<gt>YYCurtok> is declared as a C<%nonassoc> token,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   258
it can be included in C<$_[0]-E<gt>YYExpect> list whenever the input
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   259
try to use it in an associative way. This is not a bug: the token
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   260
IS expected to report an error if encountered.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   261
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   262
To detect such a thing in your error reporting sub, the following
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   263
example should do the trick:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   264
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   265
        grep { $_[0]->YYCurtok eq $_ } $_[0]->YYExpect
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   266
    and do {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   267
        #Non-associative token used in an associative expression
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   268
    };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   269
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   270
Accessing semantics values on the left of your reducing rule is done
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   271
through the method
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   272
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   273
    $_[0]->YYSemval( index )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   274
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   275
where index is an integer. Its value being I<1 .. n> returns the same values
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   276
than I<$_[1] .. $_[n]>, but I<-n .. 0> returns values on the left of the rule
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   277
beeing reduced (It is related to I<$-n .. $0 .. $n> in yacc, but you
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   278
cannot use I<$_[0]> or I<$_[-n]> constructs in Parse::Yapp for obvious reasons)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   279
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   280
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   281
There is also a provision for a user data area in the parser object,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   282
accessed by the method:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   283
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   284
    $_[0]->YYData
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   285
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   286
which returns a reference to an anonymous hash, which let you have
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   287
all of your parsing data held inside the object (see the Calc.yp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   288
or ParseYapp.yp files in the distribution for some examples).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   289
That's how you can make you parser module reentrant: all of your
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   290
module states and variables are held inside the parser object.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   291
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   292
Note: unfortunatly, method calls in Perl have a lot of overhead,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   293
      and when YYData is used, it may be called a huge number
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   294
      of times. If your are not a *real* purist and efficiency
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   295
      is your concern, you may access directly the user-space
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   296
      in the object: $parser->{USER} wich is a reference to an
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   297
      anonymous hash array, and then benchmark.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   298
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   299
If no action is specified for a rule, the equivalant of a default
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   300
action is run, which returns the first parameter:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   301
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   302
   { $_[1] }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   303
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   304
=item C<In rule actions>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   305
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   306
It is also possible to embed semantic actions inside of a rule:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   307
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   308
    typedef:    TYPE { $type = $_[1] } identlist { ... } ;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   309
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   310
When the Parse::Yapp's parser encounter such an embedded action, it modifies
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   311
the grammar as if you wrote (although @x-1 is not a legal lhs value):
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   312
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   313
    @x-1:   /* empty */ { $type = $_[1] };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   314
    typedef:    TYPE @x-1 identlist { ... } ;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   315
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   316
where I<x> is a sequential number incremented for each "in rule" action,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   317
and I<-1> represents the "dot position" in the rule where the action arises.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   318
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   319
In such actions, you can use I<$_[1]..$_[n]> variables, which are the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   320
semantic values on the left of your action.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   321
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   322
Be aware that the way Parse::Yapp modifies your grammar because of
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   323
I<in rule actions> can produce, in some cases, spurious conflicts
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   324
that wouldn't happen otherwise.  
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   325
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   326
=item C<Generating the Parser Module>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   327
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   328
Now that you grammar file is written, you can use yapp on it
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   329
to generate your parser module:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   330
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   331
    yapp -v Calc.yp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   332
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   333
will create two files F<Calc.pm>, your parser module, and F<Calc.output>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   334
a verbose output of your parser rules, conflicts, warnings, states
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   335
and summary.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   336
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   337
What your are missing now is a lexer routine.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   338
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   339
=item C<The Lexer sub>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   340
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   341
is called each time the parser need to read the next token.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   342
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   343
It is called with only one argument that is the parser object itself,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   344
so you can access its methods, specially the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   345
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   346
    $_[0]->YYData
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   347
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   348
data area.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   349
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   350
It is its duty to return the next token and value to the parser.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   351
They C<must> be returned as a list of two variables, the first one
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   352
is the token known by the parser (symbolic or literal), the second
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   353
one beeing anything you want (usualy the content of the token, or the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   354
literal value) from a simple scalar value to any complex reference,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   355
as the parsing driver never use it but to call semantic actions:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   356
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   357
    ( 'NUMBER', $num )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   358
or
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   359
    ( '>=', '>=' )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   360
or
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   361
    ( 'ARRAY', [ @values ] )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   362
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   363
When the lexer reach the end of input, it must return the C<''>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   364
empty token with an undef value:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   365
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   366
     ( '', undef )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   367
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   368
Note that your lexer should I<never> return C<'error'> as token
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   369
value: for the driver, this is the error token used for error
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   370
recovery and would lead to odd reactions.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   371
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   372
Now that you have your lexer written, maybe you will need to output
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   373
meaningful error messages, instead of the default which is to print
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   374
'Parse error.' on STDERR.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   375
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   376
So you will need an Error reporting sub.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   377
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   378
item C<Error reporting routine>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   379
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   380
If you want one, write it knowing that it is passed as parameter
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   381
the parser object. So you can share information whith the lexer
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   382
routine quite easily.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   383
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   384
You can also use the C<$_[0]-E<gt>YYErrok> method in it, which will
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   385
resume parsing as if no error occured. Of course, since the invalid
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   386
token is still invalid, you're supposed to fix the problem by
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   387
yourself.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   388
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   389
The method C<$_[0]-E<gt>YYLexer> may help you, as it returns a reference
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   390
to the lexer routine, and can be called as
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   391
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   392
    ($tok,$val)=&{$_[0]->Lexer}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   393
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   394
to get the next token and semantic value from the input stream. To
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   395
make them current for the parser, use:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   396
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   397
    ($_[0]->YYCurtok, $_[0]->YYCurval) = ($tok, $val)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   398
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   399
and know what you're doing...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   400
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   401
=item C<Parsing>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   402
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   403
Now you've got everything to do the parsing.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   404
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   405
First, use the parser module:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   406
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   407
    use Calc;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   408
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   409
Then create the parser object:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   410
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   411
    $parser=new Calc;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   412
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   413
Now, call the YYParse method, telling it where to find the lexer
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   414
and error report subs:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   415
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   416
    $result=$parser->YYParse(yylex => \&Lexer,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   417
                           yyerror => \&ErrorReport);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   418
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   419
(assuming Lexer and ErrorReport subs have been written in your current
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   420
package)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   421
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   422
The order in which parameters appear is unimportant.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   423
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   424
Et voila.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   425
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   426
The YYParse method will do the parse, then return the last semantic
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   427
value returned, or undef if error recovery cannot recover.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   428
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   429
If you need to be sure the parse has been successful (in case your
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   430
last returned semantic value I<is> undef) make a call to:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   431
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   432
    $parser->YYNberr()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   433
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   434
which returns the total number of time the error reporting sub has been called.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   435
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   436
=item C<Error Recovery>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   437
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   438
in Parse::Yapp is implemented the same way it is in yacc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   439
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   440
=item C<Debugging Parser>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   441
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   442
To debug your parser, you can call the YYParse method with a debug parameter:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   443
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   444
    $parser->YYParse( ... , yydebug => value, ... )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   445
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   446
where value is a bitfield, each bit representing a specific debug output:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   447
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   448
    Bit Value    Outputs
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   449
    0x01         Token reading (useful for Lexer debugging)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   450
    0x02         States information
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   451
    0x04         Driver actions (shifts, reduces, accept...)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   452
    0x08         Parse Stack dump
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   453
    0x10         Error Recovery tracing
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   454
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   455
To have a full debugging ouput, use
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   456
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   457
    debug => 0x1F
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   458
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   459
Debugging output is sent to STDERR, and be aware that it can produce
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   460
C<huge> outputs.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   461
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   462
=item C<Standalone Parsers>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   463
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   464
By default, the parser modules generated will need the Parse::Yapp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   465
module installed on the system to run. They use the Parse::Yapp::Driver
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   466
which can be safely shared between parsers in the same script.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   467
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   468
In the case you'd prefer to have a standalone module generated, use
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   469
the C<-s> switch with yapp: this will automagically copy the driver
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   470
code into your module so you can use/distribute it without the need
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   471
of the Parse::Yapp module, making it really a C<Standalone Parser>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   472
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   473
If you do so, please remember to include Parse::Yapp's copyright notice
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   474
in your main module copyright, so others can know about Parse::Yapp module.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   475
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   476
=item C<Source file line numbers>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   477
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   478
by default will be included in the generated parser module, which will help
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   479
to find the guilty line in your source file in case of a syntax error.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   480
You can disable this feature by compiling your grammar with yapp using
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   481
the C<-n> switch.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   482
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   483
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   484
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   485
=head1 BUGS AND SUGGESTIONS
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   486
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   487
If you find bugs, think of anything that could improve Parse::Yapp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   488
or have any questions related to it, feel free to contact the author.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   489
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   490
=head1 AUTHOR
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   491
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   492
Francois Desarmenien  <francois@fdesar.net>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   493
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   494
=head1 SEE ALSO
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   495
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   496
yapp(1) perl(1) yacc(1) bison(1).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   497
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   498
=head1 COPYRIGHT
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   499
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   500
The Parse::Yapp module and its related modules and shell scripts are copyright
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   501
(c) 1998-2001 Francois Desarmenien, France. All rights reserved.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   502
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   503
You may use and distribute them under the terms of either
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   504
the GNU General Public License or the Artistic License,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   505
as specified in the Perl README file.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   506
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   507
If you use the "standalone parser" option so people don't need to install
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   508
Parse::Yapp on their systems in order to run you software, this copyright
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   509
noticed should be included in your software copyright too, and the copyright
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   510
notice in the embedded driver should be left untouched.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   511
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   512
=cut