File Coverage

blib/lib/Parse/Highlife/Utils.pm
Criterion Covered Total %
statement 3 75 4.0
branch 0 18 0.0
condition 0 6 0.0
subroutine 1 7 14.2
pod 0 6 0.0
total 4 112 3.5


line stmt bran cond sub pod time code
1             package Parse::Highlife::Utils;
2              
3 1     1   897 use Data::Dump qw(dump);
  1         8427  
  1         1112  
4              
5             require Exporter;
6             @ISA = qw(Exporter);
7             @EXPORT_OK =
8             qw(
9             params
10             offset_to_coordinate
11             get_source_info
12             extend_match
13             dump_tokens
14             dump_ast
15             );
16              
17             sub dump_ast
18             {
19 0     0 0   my( $ast, $level ) = @_;
20 0 0         $level = 0 unless defined $level;
21            
22 0 0         if( $ast->{'category'} eq 'group' ) {
    0          
23 0           print ''.('. ' x $level)."".$ast->{'rulename'}.":\n";
24 0           map { dump_ast( $_, $level + 1 ) } @{$ast->{'children'}};
  0            
  0            
25             }
26             elsif( $ast->{'category'} eq 'leaf' ) {
27 0           my $value = $ast->{'children'};
28 0           $value =~ s/\n/\\n/g;
29 0           $value =~ s/\r/\\r/g;
30 0           $value =~ s/\t/\\t/g;
31 0           print ''.('. ' x $level)."".$ast->{'rulename'}." '".$value."'\n";
32             }
33             }
34              
35             sub dump_tokens
36             {
37 0     0 0   my( $tokens, $hide_ignored_tokens ) = @_;
38 0 0         $hide_ignored_tokens = 0 unless defined $hide_ignored_tokens;
39 0           print "#".scalar(@{$tokens})." tokens (\n";
  0            
40 0           my $t = 0;
41 0           foreach my $token (@{$tokens}) {
  0            
42 0 0 0       if( $hide_ignored_tokens && $token->{'is-ignored'} ) {
43 0           $t ++;
44 0           next;
45             }
46 0           my $classname = $token->{'token-classname'};
47 0           $classname =~ s/^.*\://g;
48 0           my $head =
49             sprintf('%4d', $t).'. chars '.
50             sprintf('%4d',$token->{'first-offset'}).'..'.
51             sprintf('%-4d',$token->{'last-offset'}).
52             ' <'.$classname.">: ";
53 0           my $value = $token->{'matched-substring'};
54 0           $value =~ s/\n/\\n/g;
55 0           $value =~ s/\r/\\r/g;
56 0           $value =~ s/\t/\\t/g;
57 0           my $head2 = sprintf('%-40s',$head)."'".$value."'";
58 0           print sprintf('%-65s',$head2).' = '.$token->{'token-name'}."\n";
59 0           $t ++;
60             }
61 0           print ")\n";
62             }
63              
64             # extend a token match with some generic info that makes it easier
65             # to handle by the tokenizer
66             sub extend_match
67             {
68 0     0 0   my( $string, $match ) = @_;
69 0           $match->{'last-offset'} = $match->{'first-offset'} + length($match->{'matched-substring'}) - 1;
70 0           $match->{'first-line'} = 0;
71 0           $match->{'last-line'} = 0;
72 0           $match->{'offset-after-match'} = $match->{'last-offset'} + 1;
73 0 0         if( exists $match->{'real-content'} ) {
74 0           $match->{'matched-substring'} = $match->{'real-content'};
75             }
76 0           return $match;
77             }
78              
79             sub params
80             {
81 0     0 0   my( $arglist, @defs ) = @_;
82 0           my( $self, %args ) = @{$arglist};
  0            
83 0           my @values;
84 0           for( my $i = 0; $i < @defs; $i += 2 ) {
85 0           my $key = $defs[$i];
86 0 0         push @values, ( exists $args{$key} ? $args{$key} : $defs[$i+1] );
87             }
88 0           return( $self, @values );
89             }
90              
91             # converts an offset into a line/column coordinate
92             sub offset_to_coordinate
93             {
94 0     0 0   my( $string, $offset ) = @_;
95 0           my $head = substr $string, 0, $offset;
96 0           my $c = 0;
97 0           my $line = 0;
98 0           my $last_line_end = 0;
99 0           while( $c < length $head ) {
100 0 0         if( substr( $head, $c, 1 ) eq "\n" ) {
101 0           $line ++;
102 0           $last_line_end = $c;
103             }
104 0           $c++;
105             }
106 0           return ($line + 1, length substr( $head, $last_line_end ));
107             }
108              
109             # returns a dump of a string with a mark at a special position
110             sub get_source_info
111             {
112 0     0 0   my( $string, $offset ) = @_;
113 0           my( $line, $column ) = offset_to_coordinate( $string, $offset );
114 0           $line --;
115 0           my $s = '';
116 0           my $l = 0;
117 0           foreach my $src_line (split /\n/, $string) {
118 0 0 0       if( $l > $line - 10 && $l <= $line ) {
119 0           $s .= sprintf('%4d',$l+1)." | ".$src_line."\n";
120             }
121 0           $l ++;
122             }
123 0           $s .= " ".(' ' x ($column - 1));
124 0           $s .= "^ don't know how to handle '".substr($string,$offset,1)."'\n";
125 0           return $s;
126             }
127              
128             1;