User since
2003-08-18
142
Artikel
BenutzerIn
Hallo,
Ich würde gerne BNF Nachrichten in einen Hash mit Referenzen entweder auf Werte oder weitere Hashes parsen.
Das Ganze sollte so etwas liefern wie zum Beispiel XML::Simple ein XML in eine Struktur parst.
Ein Beispiel für eine BNF-Nachricht wäre:
{key1={key11=value11} | key2 = value2 | key3 = {key31=value31 | key32 = value32 | key33 = {key331=value331}}}.
User since
2006-07-10
2611
Artikel
BenutzerIn
Das sollte funktionieren:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $data='{key1={key11=value11} | key2 = value2 | key3 = {key31=value31 | key32 = value32 | key33 = {key331=value331}}}';
sub parse($)
{
my $data=shift(@_);
my $rcu;
$rcu=sub
{
my $ref;
if($data=~s/^\s*\{//s)
{
$ref={};
while(index($data,'}')!=0)
{
$data=~s/^[\|\s]*(.+?)\s*=//s;
my $n=$1;
$ref->{$n}=$rcu->();
}
$data=~s/^}//;
}
else
{
$data=~s/^\s*(.+?)\s*(\||\})/$2/s;
$ref=$1;
}
return $ref;
};
return $rcu->();
}
print Dumper(parse($data))."\n";
User since
2003-08-18
142
Artikel
BenutzerIn
Exzellent! Vielen Dank!\n\n
<!--EDIT|weismat|1165508675-->
User since
2003-08-18
142
Artikel
BenutzerIn
Ich habe nur das Problem, daß ich die Routine in ein Package packen möchte und da funktioniert die Sache nicht ..Direkt in den Quellcode kopiert, ist alles fein.
Kann mir da jemand helfen?
User since
2006-07-10
2611
Artikel
BenutzerIn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $data='{key1={key11=value11} | key2 = value2 | key3 = {key31=value31 | key32 = value32 | key33 = {key331=value331|key332={key3321=value3321|key3322=value3322|key3321=value3322}|key333=value333|key334=value334}}}';
package BNF;
sub encode($)
{
my $data=shift(@_);
my $rcu;
$rcu=sub
{
my $ref;
if($data=~s/^\s*\{//s)
{
$ref={};
while(index($data,'}')!=0)
{
$data=~s/^[\|\s]*(.+?)\s*=//s;
my $n=$1;
$ref->{$n}=$rcu->();
}
$data=~s/^}//;
}
else
{
$data=~s/^\s*(.+?)\s*(\||\})/$2/s;
$ref=$1;
}
return $ref;
};
return $rcu->();
}
package main;
print Dumper(BNF::encode($data))."\n";
Und was funktioniert nicht?
User since
2003-08-18
142
Artikel
BenutzerIn
Sorry...Du hast recht...ich hatte äbhangig davon, ob es Leerzeichen zwischen den geschweiften Klammern gibt, Probleme und habe dabei übersehen, daß ich das Package selber zerstört habe....nochmals vielen Dank!
User since
2003-08-18
142
Artikel
BenutzerIn
Wie könnte ich das Programm einschränken, damit ich unter Umständen nur einschliesslich der 2. Ebene parse?
Meine längste Nachricht hat eine Länge von 1.6 MB mit 5 Ebenen und da dauert es schon Minuten - ich könnte mir vorstellen, daß ein Parsen bis zur zweiten Ebene und dann ein späteres Parsen der unteren Ebene viel schneller ist....oder sehe ich das falsch?
User since
2003-08-04
14371
Artikel
ModeratorIn
Wenn Du eine richtige BNF vorliegen hast, würde ich mir vielleicht mal
Parse::RecDescent anschauen... Allerdings weiß ich nicht, wie schnell das Ganze ist...
User since
2003-08-18
142
Artikel
BenutzerIn
Meine Messages sind im BNF-Format - nicht direkt die Grammatik.
Ich werde mal schauen, ob/wie ich das rekursive Format in ein iteratives Format umwandle...aber ich bin leider kein Experte...