> I guess whipping up a new parser is not hard...
Not as easy as it seems. I probably started from a wrong end, the logic in the actions collapse and tuple should be handled by the grammar itself, but hey: it's slow, but it works for the input.
#! /usr/bin/perl
use warnings;
use strict;
use Marpa::R2;
use open ':std', ':encoding(UTF-8)';
my $dsl = << '__DSL__';
:default ::= action => ::first
lexeme default = latm => 1
PackageList ::= ('(1') Packages (')')
Package ::= ('(') Name ('. [') Date Deps Desc Format Detail ('])')
action => assemble
Packages ::= Package Packages action => merge
| Package action => [values]
Date ::= List
Deps ::= List
| Nil
Desc ::= String
Format ::= Name
Detail ::= List
| Nil
Dot ::= dot action => dot
Nil ::= 'nil' action => nil
String ::= ('"') Quoteds ('"')
Quoteds ::= Quoted Quoteds action => concat
| Quoted
Keyed ::= (':') Name Elements action => tuple
List ::= ('(') Elements (')') action => collapse
Elements ::= Element Elements action => merge
| Element action => [values]
Element ::= number
|| Nil
| String
| Keyed
| List
| Dot
|| Name
Name ::= id_chars
Quoted ::= no_qq
| escaped_qq action => unescape
:discard ~ whitespace
whitespace ~ [\s]+
id_chars ~ [-+@\w]+
no_qq ~ [^"]
escaped_qq ~ '\"'
number ~ [0-9]+
dot ~ '.'
__DSL__
sub nil { undef }
sub dot { \'.' }
sub unescape { substr $_[1], 1 }
sub concat { $_[1] . $_[2] }
sub merge { [ $_[1], @{ $_[2] } ] }
sub assemble {
+{ name => $_[1],
date => $_[2],
dependencies => $_[3],
description => $_[4],
format => $_[5],
details => { map @{ $_->[0] }, @{ $_[6] } }
}
}
sub collapse {
if (3 == @{ $_[1] } && 'SCALAR' eq ref $_[1][1]) {
+{ $_[1][0] // "" => $_[1][2] }
} else {
$_[1]
}
}
sub tuple {
[ ('SCALAR' eq ref $_[2][0]) ? ($_[1] => $_[2][1])
: ('SCALAR' eq ref $_[2][1]) ? ($_[1] => { ($_[2][0] // "") => $
+_[2][2] })
: ($_[1] => $_[2])
]
}
my $grammar = 'Marpa::R2::Scanless::G'->new({ source => \$ds
+l });
my $recce = 'Marpa::R2::Scanless::R'->new({ grammar => $gra
+mmar,
semantics_package => 'ma
+in' });
my $input = do { local $/; <> };
$recce->read(\$input) or die;
my $value = ${ $recce->value };
use Data::Dumper;
print Dumper($_) for @$value;
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|