A solution using the Marpa::XS parser:
#!/usr/bin/perl
use warnings;
use strict;
use Marpa::XS;
use Data::Dumper;
main();
{
package MyParser;
sub pass_tree { shift }
sub create_node {
my (undef, undef, $name, undef, $value) = @_;
return [$name => $value];
}
sub create_seq {
my (undef, @nodes) = @_;
return \@nodes;
}
sub add_nodes {
my (undef, undef, $name, undef, $nodes) = @_;
return [ $name => $nodes ];
}
sub Tree {
return $_[1];
}
}
sub main {
my $grammar = init_grammar();
my $rec = init_recognizer($grammar);
my $input = do { local $/ = undef ; <DATA> };
lex($input, $rec);
while (my $val = $rec->value) {
print Dumper $val;
}
}
sub init_grammar {
my $grammar = Marpa::XS::Grammar->new
({
start => 'Tree',
actions => 'MyParser',
default_action => 'pass_tree',
rules => [
[ 'Tree', ['Node'] ],
[ 'Tree', ['Leave'] ],
[ 'Node', [qw/( Name = Value )/], '
+create_node'],
[ 'Node', [qw/( Name = NodeSeq )/], '
+add_nodes'],
{ lhs => 'NodeSeq', rhs => [qw/Node/], min => 1, a
+ction => 'create_seq' },
],
});
$grammar->precompute;
}
sub init_recognizer {
my $grammar = shift;
my $rec = Marpa::XS::Recognizer->new({ grammar => $grammar,
# trace_terminals => 1,
# trace_actions => 1,
# trace_values => 1
});
}
sub lex {
my ($input, $rec) = @_;
while (length $input) {
if ($input =~ s/^([()])//) {
my $success = $rec->read($1);
last if ! $success or $success == 0;
} elsif ($input =~ s/^([^()=]+)=([^()=]+)//) {
$rec->read('Name', $1);
$rec->read('=');
$rec->read('Value', $2);
} elsif ($input =~ s/^([^()=]+)=//) {
$rec->read('Name', $1);
$rec->read('=');
} else {
$input =~ s/^\s+// or die "Invalid input at $input\n";
}
}
die "Cannot parse: $input.\n" if $input =~ /\S/;
}
__DATA__
(S=(SN=ac2.bd)
(I1=(IN=s%1)(NM=1)
(HL=(HLD=kkk kjkjk)(ST=abdc)(HI=REM SSS)(H_M=9)(HL=72)(EB=0)
+(ER=0)(HI=E043-93A-DF0-0AB63E)(PE=aaa)(HN=DEE)(SS=NS)(SED=(APR=(PAD=k
+kk)(PN=9905)(HH=llkjk))(DD=(LLL=kkk))))
(ppp=1)(RAW=kkk)(DN=kkk)(RIN=ppp))
(PPP=1)
(AA=LLI))
Update: Hashes cannot be used easily, because the "key" can be repeated (as in HI). Switched to arrays.
Update 2: Simplified the code.
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
Outside of code tags, you may need to use entities for some characters:
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.
|
|