清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>
package LuaTidy; # 对 Lua 代码进行缩进重排 use Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw(lua_tidy); use 5.010; use strict; use warnings; use File::Slurp qw(read_file); # ---------------------------------------------- # 初始化全局变量 # global variable to save all matched string our $cluster_str = {}; our $INDENT = 2; my @observe_words = qw(function end if while repeat for do until else elsif then); # replace all the observed word to char our $observed_words = {}; our $reverse_words = {}; my $start_count = 128; foreach my $word (@observe_words) { my $char = chr($start_count); $start_count++; $observed_words->{$word} = $char; $reverse_words->{$char} = $word; } # --------------------------------------------- # 命令行接口 if (scalar @ARGV > 0) { # Get argument from command line my ($file, $indent) = @ARGV; # Indent is space $INDENT = $indent || 2; my @lines = <DATA>; my $text = join '', @lines; if (defined $file and -e $file) { # read file and save to one text $text = read_file $file; } else { say "Usage:\nperl LuaTidy.pm need_tidy.lua [ indent length ]\n"; say "Pls see sample:\n---------------------------------"; } say $text; my $code_str = lua_tidy($text, 2); say "After Tidy:\n---------------------------"; say $code_str; } # -------------------------------------- # 模块接口 # sub lua_tidy { my ($text, $indent) = @_; # conceal the do after while or for to !done! $text =~ s/\b((?:while|for)\b.*?)do/$1!done!/g; # delete all the space of all line_start and line_end $text =~ s/^\h+|\h+$//xmsg; # conceal all reserved words to char foreach my $word (keys $observed_words) { my $char = $observed_words->{$word}; $text =~ s/\b$word\b/$char/g; } my $start_class = get_class_str([qw(function if while do repeat for)]); my $end_class = get_class_str([qw(end until)]); foreach (1 .. 100) { my $t = $text =~ s/([$start_class][^$start_class]+?[$end_class])/replace_cluster($1)/ge; last if ($t eq ''); } $text = recover_words(write_text($text)); $text =~ s/!done!/do/g; return $text; } # ----------------------------------------- # 子程序 # sub replace_cluster { my ($match_str) = @_; my $number = apply_number(); my $recover_str = recover_words($match_str); $cluster_str->{$number} = $recover_str; return $number; } sub recover_words { my ($str) = @_; my %reverse_observed_words = reverse %{$observed_words}; foreach my $char (keys %reverse_observed_words) { my $word = $reverse_observed_words{$char}; $str =~ s/$char/$word/g; } return $str; } sub write_text { my ($text) = @_; foreach ( 0 .. 20 ) { # This is most import regexp use to neizhi function my $t = $text =~ s/^(\h*)(\S.*?)?(!\d{4}!)/write_indent_str($1, $2, $3)/xmge; last if ($t eq ''); } return $text; } sub write_indent_str { my ($indent, $content, $id) = @_; $content = $content || ''; my $str = $cluster_str->{$id}; $str = indent_str($str, $indent); return $indent . $content . $str; } sub indent_str { my ($str, $indent) = @_; my @lines = split /\n/, $str; my $line_number = scalar @lines; my @indent_lines = (); my $count = 0; my $indent_space = ' ' x $INDENT; foreach my $line (@lines) { $count++; if ($count > 1) { $line = $indent . $line; if ( $count < $line_number) { $line = $indent_space . $line; } } push @indent_lines, $line; } $str = join "\n", @indent_lines; } sub apply_number { state $count = 0; $count++; return sprintf("!%.4d!", $count); } # ---------------------------------------------------- # Transfer words list to class cluster to integrate in regexp # ----------------------------------------------------------- sub get_class_str { my ($list) = @_; my @array = map { $observed_words->{$_} } @{$list}; my $str = join '', @array; return $str; } # ################################################# # Debug function # ------------------------------------------------ # Check if have any conceal char have not recover # ------------------------------------------------ sub check_conceal { my ($str, $call_name) = @_; foreach my $char (keys $reverse_words) { if ($str =~ /$char/) { say "find it in call: $call_name" ; return 1; } } } # ---------------------------------------- # View cluster_str data # ---------------------------------------------- sub view_cluster { foreach my $id (sort keys $cluster_str) { my $str = $cluster_str->{$id}; $str =~ s/^\s+|\s+$//xmsg; $str = indent_str($str); } } __DATA__ local function test_defined(value, path) if defined[value] then if path:match("^getmetatable.*%)$") then out[#out+1] = string_format("s%s, %s)\n", path:sub(2,-2), defined[value]) else out[#out+1] = path .. " = " .. defined[value] .. "\n" end return true end defined[value] = path end