2016-11-11 122 views
0

我使用Perl來解析JSON文件。當一切正常時,我發現匹配的大括號很好。但是如果出現不匹配的情況,我想不出找到它的位置的好方法。perl:有沒有找到不匹配的大括號/括號/ parens等啓發式

我現在的數據是文件中大括號偏移量的排序數組(@merged) ,偏移大括號的設置爲負數。

下面是不匹配的部分:

 
    @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 
      } 
    } 

我也有關於列的信息,但我不希望算法依賴於強迫格式。

我希望將它適應perl文本,以便翻譯者只是說最後有一個不匹配的大括號。

是否有任何好的啓發式查找錯配位置?

回答

2

使用解析器,不要試圖重新發明輪子。這裏有一個例子:

#!/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"; 
} 

輸出

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

我程序的部分原因是爲了完成某些任務,部分原因是要學會編程。使用黑匣子不適用後一種功能。此外,當我使用黑盒子時,比如perl解釋器,它永遠不會告訴我括號丟失的地方。它通常只是指向文件中的最後一個括號,並將其留給我手動檢查所有括號。這就是爲什麼我試圖看看是否有一些啓發式方法可以縮小到我應該查找錯誤的地方。在XML中更容易,因爲關閉的「括號」明確地說明了它們正在關閉的內容。 – user1067305

+2

那麼,您可以在這裏查看JSON解析器的源代碼:http://cpansearch.perl.org/src/MAKAMAKA/JSON-2.90/lib/JSON.pm。一般來說,編寫解析器並不重要,您基本上需要編寫一個解析器來執行您想要的操作。 – xxfelixxx

+2

如果您在編寫新的Perl代碼時遇到困難,並且不喜歡perl -c告訴您的內容(因爲它可能不清楚問題是什麼),所以一般策略是從編譯程序開始,你添加更多的代碼,你檢查它仍然編譯。如果你有一個現有的程序,你可以嘗試註釋部分,直到它編譯,然後慢慢取消註釋代碼行以找到_real_問題。 – xxfelixxx

0

我發現它的工作原理非常時的啓發,特別是如果你強迫大約排隊打開和關閉括號。

我掃描文件,找到匹配的括號,並找到列之間的區別。這個錯誤通常與大多數比賽相比具有更大的差異。

當然,我不得不在評論或引號中忽略括號。

我已經使用了.pl和.js文件,它運行良好。