 (;GM[1]FF[4]CA[UTF-8]AP[Cgoban:2]ST[2]
RU[Japanese]SZ[19]HA[5]KM[5.50]TM[]
PW[Simon Cozens]PB[Keiko Aihara]AB[dd][pd][jj][dp][pp]
;W[df];B[fd];W[cn]
   (;B[dl])  
   (;B[fp]CR[fp]C[This is the usual response.])
   (;B[co]CR[co]C[This way is stronger still.]
    ;W[dn];B[fp])
)
---------------------------------
GameTree : "(" Sequence GameTree(s?) ")"
---------------------------------
Sequence: Node(s)
---------------------------------
Node: ";" Property(s)
Property: PropIdent PropValue(s)
---------------------------------
PropIdent : /[A-Z]+/
---------------------------------
extract_bracketed($text, '[]';
---------------------------------
PropValue : { extract_bracketed($text, '[]') }
---------------------------------
my $grammar = q{
    GameTree  : "(" Sequence GameTree(s?) ")"
    Sequence   : Node(s)
    Node       : ";" Property(s)
    Property   : PropIdent PropValue(s)
    PropIdent : /[A-Z]+/
    PropValue: { extract_bracketed($text, '[]') }
}
---------------------------------
my $sgf_parser = Parse::RecDescent->new($grammar);
---------------------------------
use strict;
use Parse::RecDescent;
my $grammar = q{
    GameTree  : "(" Sequence GameTree(s?) ")"
    Sequence   : Node(s)
    Node       : ";" Property(s)
    Property   : PropIdent PropValue(s)
    PropIdent : /[A-Z]+/
    PropValue: { extract_bracketed($text, '[]') }
};
my $sgf_parser = Parse::RecDescent->new($grammar);

undef $/; my $sgf = <DATA>;
print $sgf_parser->GameTree($sgf);

__DATA__
(;GM[1]FF[4]AP{CGoban:2]ST[2]RU{Japanese} 
PW[Honinbo Shuwa]PB[Yasuda Shusaku]
WR[7d]BR[5d]
;B[qd];W[dc];B[pq];W[oc];B[cp];W[qo]
;B[pe]C[This is the famous "Shusaku opening".])
---------------------------------
 (;GM[1]FF[4]AP[CGoban:2]ST[2]RU[Japanese]
PW[Honinbo Shuwa]PB[Yasuda Shusaku]
WR[7d]BR[5d]
;B[qd];W[dc];B[pq];W[oc];B[cp];W[qo]
;B[pe]C[This)
---------------------------------
Node     : ";" Property(s) { print "Widziaem wze!\n" }
---------------------------------
Property   : PropIdent PropValue(s)
                 { print "Widziaem wasno typu $item[1]!\n" }
---------------------------------
Property   : PropIdent PropValue(s)
             { $return = { type => $item[1], value => $item[2] } }
---------------------------------
my $prop = $sgf_parser->Property("RU[Japanese]");
print "Jestem wasnoci typu $prop->{type}, ";
print "z wartociami $prop->{value}";
---------------------------------
Property   : PropIdent PropValue(s)
             { $return = { type => $item[1], value => @{$item[2]}==1 ?
               $item[2][0] : $item[2] } }
---------------------------------
PropValue : { extract_bracketed($text, '[]') }
---------------------------------
PropValue : { my $value = extract_bracketed($text, '[]');
              ($return) = $value =~/^\[(.*)\]/ if $value; }
---------------------------------
GameTree  : "(" Sequence GameTree(s?) ")"
                 { $return = { mainline => $item[2], variations => $item[3] } }
---------------------------------
$VAR1 = {
           'variations' => [],
           'mainline' => [
                           [
                             {
                               'value' => '1',
                               'type' => 'GM'
                             },
                             {
                               'value' => '4',
                               'type' => 'FF'
                             },
                             {
                               'value' => 'CGoban:2',
                               'type' => 'AP'
                             },
                             {
                               'value' => '2',
                               'type' => 'ST'
                             },
...
---------------------------------
use strict;
use Parse::RecDescent;
my $grammar = q{
    GameTree  : "(" Sequence GameTree(s?) ")"
                 { $return = { mainline => $item[2], variations => $item[3] } }
    Sequence   : Node(s)
    Node       : ";" Property(s)
    Property   : PropIdent PropValue(s)
                 { $return = { type => $item[1], value => @{$item[2]}==1 ?
                 $item[2][0] : $item[2] } }
    PropIdent : /[A-Z]+/
    PropValue : { my $value = extract_bracketed($text), '[]');
      ($return) = ($value =~ /^\[(.*0\]/) if $value; }
};
my $sgf_parser = Parse::RecDescent->new($grammar);

undef $/; my $sgf = <DATA>;
use Data::Dumper;

my $tree = $sgf_parser->GameTree($sgf);
print Dumper($tree);
---------------------------------
PropValue : { my ($value) = extract_bracketed($text, '[]');
  ($return) = ($value =~ /^\[(.*0\]/) }
---------------------------------
$VAR1 = undef;
---------------------------------
% perl -s test.pl -RD_TRACE
---------------------------------
Method:
        Variable '.' Methodname '(' Arguments ')'
        | Variable '.' Property
        | ClassIdentifier '.' Methodname '(' Arguments ')'
        | ClassIdentifier '.' Property
---------------------------------
Method:
        Variable '.' Methodname '(' <commit> Arguments ')'
        | Varialbe '.' Property
        | ClassIdentifier '.' Methoname '(' <commit> Arguments ')'
        | ClassIdentifier '.' Property
---------------------------------
Conditional:
        "if" Cond "then" Block "end"
        | "if" Cond "then" Block "else" Block "end"
---------------------------------
Conditional:
        "if" <commit> Cond "then" Block "end"
        | "if" <commit> Cond "then" Block "else" Block "end"
---------------------------------
Conditional:
        "if" <commit> Cond "then" Block <uncommit> "end"
        | "if" <commit> Cond "then" Block "else" Block "end"
---------------------------------
conditional_modifier:
        "while" <reject>
      | "until" <reject>
      | control_modifier
---------------------------------
conditional_modifier: { $::in_modifier =1 } <reject>
    | "if" expr
       { ... $::in_modifier = 0; }
    | "unless" expr
       { ... $$::in_modifier = 0; }
---------------------------------
conditional_modifier:
     { warn "Prbuje analizowa modyfikator warunkowy!" } <reject>
    | "if" expr
    | "unless" expr
---------------------------------
subroutine: "sub" sub_declaration

block: <perl_codeblock>

sub_name: /[a-zA-Z_]\w+/

sub_declaration : block
                | sub_name vlock
                | <error>
---------------------------------
ERROR (line 1): Invalid sub declaration: Was expecting block, or sub 
                name
---------------------------------
subroutine: "sub" sub_declaration

block: <perl_codeblock>

sub_name: /[a- zA-Z_]\w+/

sub_declaration : block
                | sub_name block
                | <error: Za definicja procedury>
---------------------------------
Method:
        Variable '.' Methodname '(' <commit> Arguments ')'
        | Variable '.' Property
        | ClassIdentifier '.' Methodname '(' <commit> Arguments ')'
        | ClassIdentifier '.' Property
        | <error?>
---------------------------------
$Parse::RecDescent::skip = '';
---------------------------------
massage : header "\n" body
header : header_line(s)
Header_line : field ":" value "\n" continuation
            | field ":" value "\n"
field: ?/\w+/
value: /.*/;
continuation : " " /.*/ "\n" continuation(?)
body : body_line(s?)
body_line : /.*/ "\n"
---------------------------------
$::RD_AUTOACTION = '[@item]';
---------------------------------
$VAR1 = [
          'GameTree',
          '(',
          [
            'Sequence',
            [
              [
                'Node',
                ';',
                [
                  [
                   'Property',
                   [
                     'PropIdent',
                     'GM'
                   ],
                   [
                     '1'
                   ]
                  ],
...
---------------------------------
$::RD_AUTOACTION = 'bless [@item[1..$#item]], "SGFParser::$item[0]";';
---------------------------------
my $grammar = q{
    <autotree>

    GameTree  : "(" Sequence GameTree(s?) ")"
    Sequence   : Node(s)
    Node       : ";" Property(s)
    Property   : PropIdent PropValue(s)
    PropIdent : /[A-Z]+/
    PropValue : { my $value = extract_bracketed($text, '[]');
      ($return) = ($value =~ /^\[(.*)\]/) if $value; }
};
---------------------------------
$tree= {
    __RULE__ => "GameTree",
    __STRING1__ => "(",
    Sequence => Sequence=HASH(0x23feb8),
    GameTree => ARRAY(0x24fcd4),
    __STRING2__ => ")"
};
---------------------------------
my $grammar = q{
    GameTree  : "(" Sequence GameTree(s?) ")"
    Sequence   : Node(s)
    Node       : ";" Property(s)
    Property   : "foo"
};
---------------------------------
$::RD_AUTOSTUB = 1;
my $grammar = q{
    GameTree  : "(" Sequence GameTree(s?) ")"
    Sequence   : Node(s)
    Node       : ";" Property(s)
};
---------------------------------
structure: type "{" definition(s) "}" name modifier(s?) ";"
---------------------------------
include: "#include" filespec { $text = main::include_file($item[2]) . $text; }
---------------------------------
{ my ($fish, $fowl) = (0, 0); print "Checking for fishes and fowls\n"; }

list: item(s)
    {
        print "Found $fish and $fowl fowl\n";
    }

item: "fish"
           { $fish++; }
     | "fowl"
           { $fowl++; }
     | <error: "Neihter fish nor fowl">
---------------------------------
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
X-WR-TIMEZONE;VALUE=TEXT:Europe/London
METHOD:PUBLISH
PRODID:-//Apple Computer\, Inc//iCal 1.0//EN
X-WR-CALNAME;VALUE=TEXT:Home
VERSION:2.0
BEGIN:VEVENT
SEQUENCE:5
DTSTART;TZID=Europe/London:20020923T193000
DTSTAMP:20020913T204302Z
SUMMARY:Bert Jansch at the Camden Jazz Cafe
UID:543A3F74-D09B-11D6-8A6E-000393D74DB6
STATUS:CONFIRMED
DTEND;TZID=Europe/London:20020923T223000
END:VEVENT
...
END:VCALENDAR
---------------------------------
calendarfile: calendar(s)
calendar: "BEGIN:VCALENDAR\n" line(s) "END:VCALENDAR\n"
line: /\w+/ option(s?) ":"/.*/ "\n"
option: ";" /\w+/ "=" /[^;:]+/
---------------------------------
BEGIN:VCALENDAR
NAME:Test
END:VCALENDAR
---------------------------------
line: "END" <reject>
    | /\w+/ option(s?) ":" /.*/ "\n"
---------------------------------
line: /\w+/ <reject: $item[1] eq "END"> option(s?) ":" /.*/ "\n"
---------------------------------
calendarfile: calendar(s)
calendar: "BEGIN:VCALENDAR\n" line(s) "END:VCALENDAR\n"

line: event | dataline

event: "BEGIN:VEVENT\n" dataline(s) "END:VEVENT\n"
dataline: /\w+? <reject: $item[1] eq "END"> option(s?) ":" /.*/
option: ";" /\w+ "=" /[^;:]+/
---------------------------------
use Parse::RecDescent;
my $grammar = q{
calendarfile: calendar(s)
calendar: "BEGIN:VCALENDAR\n" line(s) "END:VCALENDAR\n"
line: event | dataline
event: "BEGIN:VEVENT\n" dataline(s) "END:VEVENT\n"
dataline: /[\w-]+/ <reject: $item[1] eq "END"> option(s?) ":" /.*/
option: ";" /\w+/ "=" /[^;:]+/
};

my $p = Parse::RecDescent->new($grammar);
use Data::Dumper;
open IN, "test.ics" or die $!;
undef $/;
print Dumper($p->calendarfile(<IN>));
---------------------------------
$VAR1 = [
          'END:VCALENDAR
'
        ];
---------------------------------
option: ";" /\w+/ "=" /[^;:]+/
    { $return = { $item[2] => $item[4] }; }
};
---------------------------------
dataline: /[\w-]+/ <reject: $item[1] eq "END"> option(s?) ":" /.*/
    { my %options = map { %$_ } @{$item{3} };
      $return = {
        key => $item[1],
        value => $item[5],
        options => \%options
      }; }
---------------------------------
event: "BEGIN:VEVENT\n" dataline(s) "END:VEVENT\n"
    { $return = {};
      for (@{$item[2]}) {
        $return->{delete $_->{key}} = $_;
      }
    }
---------------------------------
line: event     { $return = { type => "event", %{$item[1]} }; } |
      dataline { $return = { type => "data", %{$item[1]} }; }
---------------------------------
calendarfile: calendar(s)
calendar: "BEGIN:VCALENDAR\n" line(s) "END:VCALENDAR\n"
    {   $return = {};
        my @events;
        for (@{$item[2]}) {
            my $type = delete $_->{type};
            if ($type eq "event") {
                push @events, $_;
            } else {
                $return->{delete $_->{key}} = $_;
            }
        }
        $return->{events} = [ sort {$a->{DTSTART}->{value} cmp
                                    $b->{DTSTART}->{value}} @events ];
    }
---------------------------------
my $p = Parse::RecDescent->new($grammar);
use Data::Dumper;
open IN, "test.ics" or die $!;
undef $/;
my $cal = $p->calendarfile(<IN>);
for (@{$cal->[0]{events}}) {
    my $when = $_->{DTSTART}->{value};
    my $what = $_->{SUMMARY}->{value};
    $when =~ s/T.*//; # Don't care about time of day
    $when =~ s/(\d{4})(\d{2})(\d{2})/$1-$2-$3/;
    $what =~ s/\\//g;
    print "$when: $what\n";
}

2002-09-14: Leaving Drinks at the Porterhouse
2002-09-21: Star Wars
2002-09-23: Bert Jansch at the Camden Jazz Cafe
2002-09-28: .pad Party?
2002-10-03: Go Home
---------------------------------
:0 [flags] [ : [locallockfile] ]
<zero lub wicej wyrae warunkowych (kady w osobnym wierszu)>
<dokadnie jeden wiersz akcji>
---------------------------------
program: thing(s)
thing: recipe | assignment | blank
blank : /^\s+/
assignment: /^(.*)=(.*)/
recipe : ':0' flags(?) locallock(?) "\n" condition(s) action "\n"
       |  ':0' flags(?) locallock(?) "\n" action "\n"
locallock : ':' filename(?)
filename: /[\w/-+\.]+/
flags : /[HBDAaEehbfcwWir]+/
---------------------------------
action : '|' /.*/
        | '!' /.*/
        | '{' /\s+/ program '}'
        | filename
---------------------------------
condition : '*' /[*!?<>\\$]?/ /.*/ "\n"
---------------------------------
assignment: /^(.*)=(.*)/
    { my $from=$1;
      my $what;
       ($what = $2) =~ s/\$(\w+)/\$ENV{$1}/g
       $return = "\$ENV{$from}=qq($what)"; }
---------------------------------
action : '|' /.*/
            { $return = qq{\$item->pipe("$item[2]");}  ; }
          | '!' /.*/
            { $return = qq{\$item->resend('$item[2]');} ; }
---------------------------------
|'{' program '}'
  { $return = $item[2] }
|filename
  { $return = qq{\$item->accept("$item[1]");} }
---------------------------------
flag: /[HBDAaEehbfcwWir]+/
        { %::flags = map { $_=> 1 } split //, $item[1];
         $return = $::flags{E} ? " elsif " : "if"; }

condition : '*' /[*!?<>\\$]?/ /.*/ "\n"
        { $return = main::parse_condition($item[2], $item[3])}
---------------------------------
recipe : { %main::flags = (); } <reject>
---------------------------------
recipe : ':0' flags(?) locallock(?) "\n" condition(s) action "\n"
    {
      $return = "if" unless @{$item[2]}; # Jeeli nie ma adnej opcji
      $return .= "@$item[2]} ("; # "if" lub "elsif" jeeli okrelono opcje
      $return .= join(" and\n\t". @{$item[5]});
---------------------------------
$return .= ")\n{".
    main::indent($item[6] . ($main::flags{c} ? "" :"\n exit 1;\n"))
   ."}\n";
}
---------------------------------
recipe : ':0" flags(?) locallock(?) "\n" condition(s) action "\n"
    { 
      $return = "if " unless @{$item[2]}; # Jeeli nie ma adnej opcji
      $return .= "@{$item[2]} ("; # "if" lub "elsif" jeeli okrelono opcje
      $return .= join(" and\n\t", @{$item[5]});
      $return .= ")\n{".
          main::indent($item[6] . ($main::flags{c} ? "" :"\n exit 1;\n"))
         ."}\n";
    }
      | ':0' flags(?) locallock(?) "\n" action "\n"
    {
     if ("@{$item[2]}" eq "else") {$return = "else " }
     $return . = "{ " .
         main::indent($item[5] . ($main::flags{c} ? "" :"\n exit 1;\n"))
        ."}\n";
    }
---------------------------------
my $parser = Parse::RecDecent->new($grammar) or die;
undef $/;
my $data = <ARGV>;
$data =~ s/#.*//g;
my $program = $parser->program($data);

print 'use Mail::Audit; my $item = Mail::Audit->new();', "\n";
print $program;
print "\n\$item->accept()";
---------------------------------
:0 c
* ^From.*peter
* ^Subject:.*compilers
! william@somewhere.edu

:0
* ^From.*peter
* ^Subje4ct:.*compilers
petcompil
---------------------------------
use Mail::Audit, my $item = Mail::Audit->new();
if ($item->header() =~ /^From.*peter/i and
        $item->$item->header() =~ /^Subject:.*compilers/i)
{       $item->resend('william@somewhere.edu');}

if ($item->header() =~ /^From.*peter/i and
        $item->header() =~ /^Subject:.*compilers/i)
{       $item->accept("petcompil");
        exit 1;
}

$item->accept()
---------------------------------
a = 25
b = 30 
a + b
55
---------------------------------
%{
double vbltable[26];
%}

%union {
    double dval;
    int vblno;
}
%token <vblno> NAME
%token <dval> NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS

%type <dval> expression
%%
statement_list:    statement '\n'
    |    statement_list statement '\n'
    ;

statement:   NAME '=' expression   { vbltable[$1] = $3; }
    |    expression       { print("= %g\n", $1); }
    ;

expression:    expression '+' expression { $$ = $1 + $3; }
    |    expression '-' expression { $$ = $1-$3; }
    |    expression '*' expression { $$ = $1 * $3; }
    |    expression '/' expression
                {    if($3 == 0.0)
                        yyerror("dzielenie przez zero");
                    else
                        $$ = $1 / $3;
                }
    |    '-' expression %prec UMNIUS    { $$ = -$2; }
    |    '(' expression ')'    { $$ = $2; }
    |    NUMBER
    |    NAME            { $$ = vbltable[$1]; }
    ;
%%
---------------------------------
%{ my %symtab; %}
%token NAME
%token NUMBER
%left '-' '+'
%left '*' '
%nonassoc UMINUS
%%

statement_list: statement '\n'
    | statement_list statement '\n'
    ;

statement: NAME '=' expression { $symtab{$_[1]} = $_[3]; }
    | expression {  print "= ", $_[1], "\n"; }
    ;

expression:
    expression '+' expression { $_[1] + $_[3] }
    | expression '-' expression { $_[1] - $_[3] }
    | expression '*' expression { $_[1] * $_[3] }
    | expression '/' expression
                  {     if ($_[3] == 0)
                           { $_[0]->YYError("dzielenie przez zero") }
                        else
                           { $_[1] / $_[3] }
                  }
    | '-' expression %prec UMINUS { -$_[2] }
    | '(' expression ')' { $_[2] }
    | NUMBER
    | NAME { $symtab{$_[1]} }
    ;

%%
---------------------------------
sub lex {
#    print " Lexer called to handle (".$_[0]->YYData->{DATA}.")\n"
     $_[0]->YYData->{DATA} =~ s//^ +//;
     return ('', undef) unless lenght $_[0]->YYData->{DATA};

     $_[0]->YYData->{DATA} =~ s/^(\d+)// and return ("NUMBER", $1);
     $_[0]->YYData->{DATA} =~ s/^([\n=+\(\)\-\/*])//    and return ($1, $1);
     $_[0]->YYData->{DATA} =~ s/^(\w+)//    and return ("NAME", $1);
     die "Unknown token (".$_[0]->YYData->{DATA}."\n";
}
---------------------------------
% yapp Calc.yapp
%
---------------------------------
my @lex = qw(
    NUMBER \d+
    NAME \w+
    "+" "+"
    "-" "-"
    "*" "*"
    "/" "/"
    "=" "="
    "(" "("
    ")" ")"
)
my $lexer = Parse::Lex->new(@lex);
$lexer->from(\*STDIN);

sub lex {
    my $token = $lexer->next;
    return ('', undef) if $lexer->eoi;
    return ($token->name, $token->getstring);
}
---------------------------------
sub lex {
    $_[0]->YYData->{DATA} =~ s/^ +//;
    return ('', undef) unless lenght $_[0]->YYData->{DATA};
    $_[0]->YYData->{DATA} =~ s/^(\d+)// and return ("NUMBER', $1);
    $_[0]->YYData->{DATA} =~ s/^([\n=+\(\)\-\/*]))//   and return ($1, $1);
    $_[0]->YYData->{DATA} =~ s/^(\w+)//    and return ("NAME", $1);
    die "Unknown token (".$_[0]->YYData->{DATA}->{DATA}.")\n";
}

use Calc;
my $p = Calc->new();
under $/;
$p->YYData->{DATA} = <STDIN>;
$p->YYParse(YYlex => \&lex);
---------------------------------
% perl calc

a = 2+4
b= a * 20
b + 15
^D

=135
---------------------------------
sub lex {
    $_[0]->YYData->{DATA} =~ s/^ +//;
    unless (lenght $_[0]->YYData->{DATA}) {
        return ('', undef if eof STDIN;
        $_[0]->YYData->{DATA} = <STDIN>;
        $_[0]->YYData->{DATA} =~ s/^ +//;
    }
    
    $_[0]->YYData->{DATA} =~ s/^(\d+)// and return ("NUMBER", $1);
    $_[0]->YYData->{DATA} =~ s/^([\n=+\(\)\-\/*])//    and return (%1, $1);
    $_[0]->YYData->{DATA} =~ s/^(\w+)//    and return ("NAME", $1);
    die Unknown token (".$_[0]->YYData->{DATA}.")\n";
}
---------------------------------
package DumpLinks;
use strict;
use base 'HTML::Parser';
---------------------------------
sub start {
   my ($self, $tag, $attr) = @_;
   return unless $tag eq "a";
   $self->{_this_url} = $attr->{href};
   $self->{_in_link} = 1;
}
---------------------------------
sub text {
    my ($self, $text) = @_;
    return unless $self->{_in_link};
    $self->{_urls)->{$self->{_this_url}} .= $text;
}
---------------------------------
<a href="http://www.perl.com/">The <code>Perl</code> home page</a>
---------------------------------
sub end {
    my ($self, $tag) = @_;
    $self->{_in_link} = 0 if $tag eq "a";
}
---------------------------------
package DumpLinks;
use strict;
use base 'HTML::Parser';

sub start {
    my ($self, $tag, $attr) = @_;
    return unless $tag eq "a";
    $self->{_this_url} = $attr->{href};
    $self->{_in_link} = 1;
}

sub text {
    my ($self, $text) = @_;
    return unless $self->{_in_link};
    $self->{_urls)->{$self->_this_url}} .= $text;
}

sub end {
    my ($self, $tag) = @_;
    $self->{_in_link} = 0 if $tag eq "a";
}
---------------------------------
Use DumpLinks;
my $parser = DumpLinks->new();
$parser->parse_file("index.html");
for (keys %{$parser->{_urls}) {
    print qq{Link do $_ (Opis linku: "}. $parser->{_urls}->{$_}. qq{")\n};
}
---------------------------------
use HTML::LinkExtor;
my $parser = HTML::LinkExtor->new();
$parser->parse_file("index.html");
for ($parser->links) {
    my ($tag, %attrs) = @$_;
    print $attrs{href},"\n";
}
---------------------------------
<opdesc>
<opcode name="nop" input="Pop0" output="Push0" args="InlineNone" o1="0xFF o2="0x00"
flow="next"/>
<opcode name="break" input="Pop0" output="Push0" args="InlineNone" o1="0xFF"
o2="0x01" flow="break"/>
<opcode name="ldarg.0" input="Pop0" output="Push1" args="InlineNone" o1="0xFF"
o2="0x02" flow="next"/>
<opcode name="ldarg.1" input="Pop0" output="Push1" args="InlineNone" o1="0xFF"
o2="0x03" flow="next"/>
...
</opdesc>
---------------------------------
% perl -Mdata::Dumper -MXML::Simple -e
'print Dumper XMLin("/usr/local/share/mono/cil/cil-opcodes.xml")'

$VAR1 = {
          'opcode' => {
                        'stloc.2' => {
                                       'args' => 'InlineNone',
                                       'input' => 'Pop1',
                                       'o1' => '0xFF',
                                       'o2 => '0x0C',
                                       'output' => 'Push0',
                                       'flow' => 'next'
                                     },
                        'stloc.3' => {
                                       'args' => 'InlineNone',
                                       'input' => 'Pop1',
                                       'o1' => '0xFF;,
                                       'o2' => '0x0D',
                                       'output' => 'Push0',
                                       'flow' => 'next'
                                     },
                        ...
                       }
};
---------------------------------
use XML::Simple;
my $opcodes = XMLin("/usr/local/share/mono/cil/cil-opcodes.xml");
my $shl = $opcodes->{opcode}->{shl};
print "shl pobiera argumenty, wykonujc ".$shl->{input}."\n";
print "a wynik zwraca, wykonujc ".$shl->{output}."\n";
---------------------------------
$opcodes->{opcode}->{hcf} = {
                             'args' => 'InlineNone',
                             'input' = 'Pop0',
                             'o1' => '0xFF',
                             'o2' => '0xFF',
                             'output' => 'Push0',
                             'flow' = > 'explode'
                            };

print XMLout($opcodes);
---------------------------------
<opcode args="InlineNone" input="Pop0" o1="0xFF" o2="0xFF" output="Push0"
flow="explode" name="hcf" />
---------------------------------
% perl =Mdata::Dumper -Mconfig::Auto -e 'print Dumper Config::Auto::parse("/etc/smb.
conf")'

$VAR1 = {
          'global' => {
                        'guest account' => 'unknown',
                        'client code page' => 437,
                        'encrypt password' => 'yes',
                        'coding system' => 'utf8'
                       },
          'homes' => {
                        'read only' => 'no',
                        'browseable' => 'no',
                        'comment' => 'User Home Directories',
                        'create mode' => '0750'
                      } 
        };

