chiark / gitweb /
dump-to-assgn: Add a script to convert dumps into `read_tree' form.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 6 Sep 2024 20:58:32 +0000 (21:58 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 6 Sep 2024 20:58:32 +0000 (21:58 +0100)
Also pretty-prints `read-tree' format.

dump-to-assgn [new file with mode: 0755]

diff --git a/dump-to-assgn b/dump-to-assgn
new file mode 100755 (executable)
index 0000000..22db491
--- /dev/null
@@ -0,0 +1,81 @@
+#! /usr/bin/perl -w
+
+use autodie;
+use strict;
+
+use Getopt::Std;
+
+our $opt_r;
+getopts "r";
+
+sub node ($) {
+  my ($k) = @_;
+  return { key => $k, left => undef, right => undef, flags => "" };
+}
+
+sub read_tree ($);
+sub read_tree ($) {
+  my ($s) = @_;
+  if ($s =~ /^ \s* _ \s* (.*) $/x) { return undef, $1; }
+  $s =~ /^ \s* \( \s* (.*) $/x or die "bad string";
+  (my $left, $s) = read_tree $1;
+  $s =~ /^ \s* ([*]*) \s* (\d+) \s* (.*) $/x or die "bad string";
+  (my $flags, my $key) = ($1, $2);
+  (my $right, $s) = read_tree $3;
+  $s =~ /^ \s* \) \s* (.*) $/x or die "bad string";
+  my $node = node $key;
+  $node->{left} = $left; $node->{right} = $right; $node->{flags} = $flags;
+  return $node, $1;
+}
+
+my @N = ();
+my @LV = ();
+my $SP = 0;
+
+my $firstp = 1;
+my $tree = undef;
+LINE: while (<>) {
+  chomp;
+
+  if ($firstp && /^\s*[(_]/) {
+    ($tree, my $tail) = read_tree $_;
+    $tail =~ /^ \s* $/x or die "bad string";
+    last LINE;
+  }
+
+  $firstp = 0;
+  m{^ \s+ \#0x[0-9a-f]{8} \s+  \(n \s* = \s* \d+\)
+      (\s+) \(([ *+=-])\) (?: \s+ (0x[0-9a-f]{8} \s* \$)) \s+ (\d+) $}x
+    or die "bad line `$_'";
+  my $lv = length $1;
+  my $sigil = $2;
+  my $weight = $3;
+  my $key = $4;
+
+  my $node = node $key;
+  if ($opt_r && $sigil eq "*") { $node->{flags} .= "*"; }
+  if (defined $weight) { $node->{flags} .= $weight . " "; }
+  my $left = undef;
+  while ($SP && $LV[$SP - 1] > $lv)
+    { $SP--; my $n = $N[$SP]; $n->{right} = $left; $left = $n; }
+  $node->{left} = $left; $N[$SP] = $node; $LV[$SP] = $lv; $SP++;
+}
+while ($SP) { $SP--; my $n = $N[$SP]; $n->{right} = $tree; $tree = $n; }
+
+sub show_tree ($$$$);
+sub show_tree ($$$$) {
+  my ($node, $dp, $lp, $nl) = @_;
+  if ($node->{flags} eq "*") { $dp = ($dp&-2) + 1; }
+  if ($node->{left}) {
+    show_tree $node->{left}, $dp + 1, $lp + 1, $nl;
+    print "\n" . "\t" x $dp . $node->{flags} . $node->{key};
+  } else {
+    print "\n" if $nl;
+    print "\t" x $dp . "(" x $lp . "_ " . $node->{flags} . $node->{key};
+  }
+  if ($node->{right}) { show_tree $node->{right}, $dp + 1, 1, 1; }
+  else { print " _"; }
+  print ")";
+}
+show_tree $tree, 1, 1, 0;
+print "\n";