清华大佬耗费三个月吐血整理的几百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