【问题标题】:perl: Is there a heuristic for finding mismatched braces/brackets/parens etcperl:是否有用于查找不匹配的大括号/方括号/括号等的启发式方法
【发布时间】:2017-03-25 05:17:20
【问题描述】:

我正在使用 perl 来解析一个 json 文件。当一切正常时,我发现匹配的大括号很好。但是如果有不匹配的地方,我想不出找到它的好方法。

此时我的数据是一个排序数组 (@merged) 文件中大括号的偏移量,右大括号的偏移量设置为负数。

这是进行匹配的部分:

@stack=(); foreach $val (@merged) # 遍历合并数组 { if ($val>0) { push @stack, $val;} # 将每个开启者压入堆栈 否则 { $opn = 弹出 @stack; # 当关闭器出现时,弹出前一个开启器 @tmp = ($opn, abs $val); # 一个匹配的数组 推@matches,[@tmp]; # 所有匹配的数组 } }

我也有关于该列的信息,但我不希望算法依赖于强制格式。

我也想把它改编成 perl 文本,因为当翻译者只是说结尾有一个不匹配的大括号时。

有没有什么好的启发式方法可以找到不匹配的位置?

【问题讨论】:

    标签: perl heuristics


    【解决方案1】:

    使用解析器,不要试图重新发明轮子。这是一个例子:

    #!/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 = $@;
    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}}'
    .............................................^
    

    【讨论】:

    • 我编程的部分原因是为了完成一些事情,部分原因是为了学习编程。使用黑匣子不具备后一种功能。此外,当我使用黑匣子时,比如 perl 解释器,它永远不会告诉我括号在哪里丢失。它通常只指向文件中的最后一个括号,让我费力地手动检查所有括号。这就是为什么我试图看看是否有一些启发式方法可以将其缩小到我应该寻找错误的地方。在 XML 中更容易,因为右“括号”明确说明了它们要关闭的内容。
    • 嗯,你可以在这里查看 JSON 解析器的源代码:cpansearch.perl.org/src/MAKAMAKA/JSON-2.90/lib/JSON.pm。一般来说,编写解析器并非易事,您基本上需要编写一个解析器来做您想做的事情。
    • 如果您在编写新的 perl 代码时遇到问题,并且不喜欢 perl -c 告诉您的内容(因为可能不清楚问题是什么......),一般的策略是从一个编译程序开始,当你添加更多代码时,你检查它是否仍然可以编译。如果您有一个现有的程序,您可以尝试注释掉部分直到它编译,然后慢慢取消注释代码行以找到真正的问题。
    【解决方案2】:

    我发现了一种在很多时候都有效的启发式方法,尤其是当你强迫性地排列左括号和右括号时。

    我扫描文件,找到匹配的括号,并找出列之间的差异。该错误通常比大多数匹配项具有更大的差异。

    当然,我必须忽略 cmets 或引号中的括号。

    我已经将它与 .pl 和 .js 文件一起使用,效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多