2016-11-11 3 views
0

Ich benutze Perl, um eine JSON-Datei zu analysieren. Wenn alles in Ordnung ist, finde ich passende Klammern gut. Aber wenn es ein Missverhältnis gibt, kann ich mir keinen guten Weg vorstellen, wo es ist.Perl: Gibt es eine Heuristik für das Finden von nicht übereinstimmenden Klammern/Klammern/Parens usw.

Meine Daten an dieser Stelle ist eine sortierte Array (@merged) der Offsets der geschweiften Klammern in der Datei, mit Offsets der schließenden geschweiften Klammern negativ gesetzt.

Hier ist der Abschnitt, der die passenden tut:

 
    @stack=(); 
    foreach $val (@merged) # go through merged array 
    { if ($val>0) { push @stack, $val;} # push every opener onto a stack 
     else { $opn = pop @stack; # when a closer comes up, pop previous opener 
       @tmp = ($opn, abs $val); # array of one match 
       push @matches, [@tmp]; # the array of all matches 
      } 
    } 

ich auch Informationen über die Spalte, aber ich will nicht der Algorithmus auf Zwang Formatierung abhängig zu sein.

Ich möchte dies auch an Perl Text anpassen, für die Zeiten, wenn der Übersetzer nur sagt, es gibt eine unübertroffene Klammer am Ende.

Gibt es irgendwelche guten Heuristiken, um den Ort des Mismatch zu finden?

Antwort

2

Verwenden Sie einen Parser, versuchen Sie nicht, das Rad neu zu erfinden. Hier ein Beispiel:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use JSON qw(decode_json encode_json); 

my $data = { foo => 'bar', baz => [1,2,3], qux => { abc => 1, def => 2, ghi => 3} }; 
my $json = encode_json($data); 

my $error_json = $json; 
$error_json =~ s|\]||; # Remove a closing square bracket 

eval { 
    my $error_data = decode_json($error_json); # Will throw an error 
}; 
my $error = [email protected]; 
if ($error) { 
    print "JSON Error : $error"; 
    my ($char_pos) = $error =~ m|at character offset (\d+)|; 
    print "Original : '$json'\n"; 
    print "Error  : '$error_json'\n"; 
    print ".............."; 
    print "."x($char_pos) . "^\n"; 

} else { 
    die "should not get here...something went wrong"; 
} 

Ausgabe

JSON Error : , or ] expected while parsing array, at character offset 31 (before ":{"abc":1,"ghi":3,"d...") at foo.pl line 15. 
Original : '{"foo":"bar","baz":[1,2,3],"qux":{"abc":1,"ghi":3,"def":2}}' 
Error  : '{"foo":"bar","baz":[1,2,3,"qux":{"abc":1,"ghi":3,"def":2}}' 
.............................................^ 
+0

Ein Teil des Grundes, den ich programmiere, ist, etwas zu erledigen, und ein Teil des Grundes ist es zu lernen, zu programmieren. Die Verwendung einer Blackbox dient nicht dieser letzteren Funktion. Außerdem, wenn ich eine Blackbox benutze, sagen wir einen Perl-Interpreter, sagt es mir nie, wo die Klammer fehlt. Es zeigt normalerweise nur auf die letzte Klammer in der Datei und überlässt es mir mühsam, manuell alle Klammern zu überprüfen. Deshalb versuche ich zu sehen, ob es eine Heuristik gibt, die es eingrenzen kann, wo ich nach dem Fehler suchen soll. Es ist einfacher in XML, da die engen "Klammern" explizit sagen, was sie schließen. – user1067305

+2

Nun, Sie können die Quelle des JSON-Parsers hier sehen: http://cpansearch.perl.org/src/MAKAMAKA/JSON-2.90/lib/JSON.pm. Im Allgemeinen ist das Schreiben eines Parsers nicht-trivial und Sie müssen im Grunde einen schreiben, um zu tun, was Sie tun möchten. – xxfelixxx

+2

Wenn Sie Probleme haben, neuen Perl-Code zu schreiben, und nicht mögen, was das Perl -c Ihnen sagt (weil es unklar sein kann, was das Problem ist ..), ist die allgemeine Strategie, mit einem kompilierenden Programm und als zu beginnen Wenn Sie mehr Code hinzufügen, überprüfen Sie, ob der Code noch kompiliert wird. Wenn Sie über ein vorhandenes Programm verfügen, können Sie versuchen, Abschnitte auszukommentieren, bis es kompiliert wird, und Codezeilen dann langsam auskommentieren, um das _real_ Problem zu finden. – xxfelixxx

0

ich eine Heuristik gefunden, die viel von der Zeit arbeitet, besonders wenn Sie zwanghaft sind über Öffnung Schlange und Klammern schließen.

Ich scanne die Datei, finde passende Klammern und finde den Unterschied zwischen den Spalten. Der Fehler unterscheidet sich gewöhnlich von den meisten Spielen.

Natürlich muss ich Klammern in Kommentaren oder Anführungszeichen ignorieren.

Ich habe dies mit .pl und .js-Dateien verwendet, und es funktioniert gut.

Verwandte Themen