chiark / gitweb /
auditor wip semiparse fixes
[dgit-junk.git] / i18n-diff-auditor
index 8252c3f1ba4d6f9b5517c2b8c08c8a74a25f98be..7398a8ec254ce296402c17ff581a302ed86b0a59 100755 (executable)
@@ -76,6 +76,7 @@ sub prep_perlop () {
        next if m{^list operators};
        s{ and unary.*}{};
        s{ etc\. }{ };
+       s{\?\:}{ ? : };
        foreach my $op (split /\s+/) {
            next unless length $op;
            next if $op =~ m{^\w+$};
@@ -98,7 +99,7 @@ sub semiparse ($) {
     my @o;
     for (;;) {
        s{^\s+}{};
-       if (s{^[\$\@\%][_0-9a-zA-Z]+}{}) {
+       if (s{^[\$\@\%]?[_0-9a-zA-Z]+}{}) {
            push @o, { T => 'ident', L => $& };
        } elsif (s{^\<\<('?)([A-Z_]+)\1}{}) {
            my ($q,$d) = ($1,$2);
@@ -106,17 +107,27 @@ sub semiparse ($) {
            s{^
                 (             .* \n    )
                 ( (?: (?! $d) .* \n )* )
-              }{ $1 } or die "missing end of here doc $d\n";
+                          $d     \n
+              }{ $1 }x or die "missing end of here doc $d\n";
            $o[$#o]{V} = $2;
-       } elsif (s{^ (["'])( (?:  [^\\] | \\ \1  )* )}{}x) {
+       } elsif (s{^ (["'])( (?: [^\\'"]
+                               | \\ [^"']
+                               | (?! \1 ) [^"]
+                              )*
+                       \1 )}{}x) {
            my ($q,$v) = ($1,$2);
            push @o, { T => 'string', Q => $q, V => $v };
-       } elsif (s{^$perlop_re}{}) {
+       } elsif (s{^$perlop_re|\;}{}) {
            push @o, { T => 'op', L => $& };
        } elsif (s/[[{(]//) {
            push @o, { T => 'bra', L => $& };
        } elsif (s/[]})]//) {
            push @o, { T => 'ket', L => $& };
+       } elsif (s/^( [\$\@\%] )( \{ )//x) {
+           push @o, { T => 'deref', L => $1 },
+                    { T => 'bra',   L => $2 };
+       } elsif (s/^ [\$\@\%] [^[^{] //x) {
+           push @o, { T => 'specvar', L => $& };
        } elsif (!length) {
            last;
        } else {
@@ -124,9 +135,10 @@ sub semiparse ($) {
            die "cannot tokenise \`$&'";
        }
     }
+    return @o;
 }          
 
-sub analyse_chunk () {
+sub analyse_chunk_core () {
     die "plain deletion\n" unless defined $after;
     die "plain insertion\n" unless defined $before;
     my @before = semiparse $before;
@@ -135,6 +147,21 @@ sub analyse_chunk () {
     flush STDOUT;
 }
 
+sub analyse_chunk () {
+    for (;;) {
+       eval { analyse_chunk_core(); };
+       return unless length $@;
+       if ($@ =~ m{^missing end of here doc (\S+)\n}) {
+           # fudge this
+           $before .= "\n$1\n";
+           $after .= "\n$1\n";
+           next;
+       } else {
+           die $@;
+       }
+    }
+}
+
 for ($ifilehead = 0; l_ok $ifilehead; $ifilehead++) {
     m{^diff} or next;
     while (l_ok $ifilehead and m{^diff|^index|^---|^\Q+++\E}) { $ifilehead++ }
@@ -148,7 +175,8 @@ for ($ifilehead = 0; l_ok $ifilehead; $ifilehead++) {
                    $ichunkend = $i;
                    eval { analyse_chunk(); 1; };
                    if (length $@) {
-                       print Dumper($ichunkstart, $ichunkend,
+                       print Dumper('REPORT',
+                                    $ichunkstart, $ichunkend,
                                     $before, $after,
                                     $@);
                    }