Pascal代码自动格式化

const
    WEnter=7;
    key=13;
    next_line:array[1..WEnter]of string=(';','begin','else','then','repeat','do','var');
    key_word:array[1..key]of string=('begin','end','function','procedure','var','if','else','repeat','until','while','type','const','for');//关键的语句(需要缩进的)
    suojin=1;
    maxn=100;
var
    i,j,t,long:longint;
    s:string;
    pg,pg_key:array[1..maxn]of string;
    kg:array[1..maxn]of longint;
    full:array[1..maxn]of boolean;
function noAlphabat(s:string):boolean;这个字符串不全为空格
    begin
        if s='' then
            exit(true);
        while s[1]=' ' do
            begin
                delete(s,1,1);
                if s='' then break;
            end;
        if s='' then
            exit(true);
        exit(false);
    end;
procedure Enterat(x,y:longint);在x,y的地方按一个回车
    var
        i:longint;
        s:string;
    begin
        for i:=long downto x+1 do
            pg[i+1]:=pg[i];
        pg[x+1]:='';
        s:=copy(pg[x],y,length(pg[x])-y+1);
        pg[x]:=copy(pg[x],1,y-1);
        pg[x+1]:=s;
        long:=long+1;
    end;
function next(i:longint):longint;//找与第i行后9含)第一个begin对应的end
    var
        t,j:longint;
    begin
        t:=0;
        for j:=i to long do
            begin
                if pg_key[j]='begin' then
                    t:=t+1;
                if pg_key[j]='end' then
                    t:=t-1;
                if t=0 then
                    exit(j);
            end;
        writeln('Pairing error with begin-end!');
        //close(output);
        halt;
    end;
function next2(i:longint):longint;//找与第i行后(含)的第一个repeat配对的until
    var
        t,j:longint;
    begin
        t:=0;
        for j:=i to long do
            begin
                if pg_key[j]='repeat' then
                    t:=t+1;
                if pg_key[j]='until' then
                    t:=t-1;
                if t=0 then
                    exit(j);
            end;
        writeln('Pairing error with repeat-until!');
        //close(output);
        halt;
    end;
procedure dfs(l,r,t:longint);//第l到r区间里的代码格式化(初始值t个空格)
    var
        i,k:longint;
        alldo,had_done:boolean;
    begin
        if l>r then
            exit;
        for i:=l to r do
            kg[i]:=t;
        alldo:=true;
        for i:=l to r do
            if pg_key[i]<>'do' then
                alldo:=false;
        if alldo then//全部不需缩进则跳出
            exit;
        i:=l;
        while i<=r do
            begin
                had_done:=false;
                if pg_key[i]='begin' then//begin处理
                    begin
                        dfs(i+1,next(i)-1,t+1);
                        i:=next(i)+1;
                        had_done:=true;
                    end;
                if pg_key[i]='repeat' then//repeat处理
                    begin
                        had_done:=true;
                        dfs(i+1,next2(i)-1,t+1);
                        i:=next2(i)+1;
                    end;
                if (pg_key[i]='if')or(pg_key[i]='while')or(pg_key[i]='for') then//if、while、for处理(共同点是后面可以加begin-end、也可以加do)
                    begin
                        had_done:=true;
                        if pg_key[i+1]='do' then
                            begin
                                dfs(i+1,i+1,t+1);
                                if pg_key[i+2]='else' then //else后相同处理
                                    begin
                                        if pg_key[i+3]='do' then
                                            begin
                                                dfs(i+3,i+3,t+1);
                                                i:=i+4;
                                            end;
                                        if pg_key[i+3]='begin' then
                                            begin
                                                dfs(i+3,next(i+3),t+1);
                                                i:=next(i+3)+1;
                                            end;
                                        if pg_key[i+3]='repeat' then
                                            begin
                                                dfs(i+3,next2(i+3),t+1);
                                                i:=next2(i+3)+1;
                                            end;
                                    end
                                else
                                    i:=i+2;
                            end;
                        if pg_key[i+1]='begin' then
                            begin
                                dfs(i+1,next(i+1),t+1);
                                if pg_key[next(i+1)+1]='else' then
                                    begin
                                        if pg_key[next(i+1)+2]='do' then
                                            begin
                                                dfs(next(i+1)+2,next(i+1)+2,t+1);
                                                i:=next(i+3);
                                            end;
                                        if pg_key[next(i+1)+2]='begin' then
                                            begin
                                                dfs(next(i+1)+2,next(next(i+1)+2),t+1);
                                                i:=next(next(i)+2)+1;
                                            end;
                                        if pg_key[next(i+1)+2]='repeat' then
                                            begin
                                                dfs(next(i+1)+2,next2(next(i+1)+2),t+1);
                                                i:=next2(next(i+1)+2)+1;
                                            end;
                                    end
                                else
                                    i:=next(i+1)+1;
                            end;
                        if pg_key[i+1]='repeat' then
                            begin
                                dfs(i+1,next2(i+1),t+1);
                                if pg_key[next2(i+1)+1]='else' then
                                    begin
                                        if pg_key[next2(i+1)+2]='do' then
                                            begin
                                                dfs(next2(i+1)+2,next2(i+1)+2,t+1);
                                                i:=next2(i+3);
                                            end;
                                        if pg_key[next2(i+1)+2]='begin' then
                                            begin
                                                dfs(next2(i+1)+2,next(next2(i+1)+2),t+1);
                                                i:=next(next2(i)+2)+1;
                                            end;
                                        if pg_key[next2(i+1)+2]='repeat' then
                                            begin
                                                dfs(next(i+1)+2,next2(next2(i+1)+2),t+1);
                                                i:=next2(next2(i+1)+2)+1;
                                            end;
                                    end
                                else
                                    i:=next2(i+1)+1;
                            end;
                    end;
                if (pg_key[i]='procedure')or(pg_key[i]='function') then
                    begin
                        had_done:=true;
                        dfs(i+1,next(i+1),t);
                        i:=next(i+1)+1;
                    end;
                if (pg_key[i]='var')or(pg_key[i]='type')or(pg_key[i]='const')then
                    begin
                        had_done:=true;
                        k:=i;
                        while pg_key[k+1]='do' do
                            k:=k+1;
                        dfs(i+1,k,t+1);
                        i:=k+1;
                    end;
                if not had_done then
                    i:=i+1;
            end;
    end;
begin
    long:=0;
    while not eof do
        begin
            long:=long+1;
            readln(pg[long]);
        end;
    for i:=1 to long do
        begin
            t:=0;
            while (pg[i]<>'')and(pg[i][1]=#9) do
                begin
                    t:=t+1;
                    delete(pg[i],1,1);
                end;
            for j:=1 to t*4 do
                pg[i]:=' '+pg[i];
        end;
    i:=1;
    while i<=long do//黏在一起的语句拆开
        begin
            for j:=1 to WEnter do
                if pos(next_line[j],pg[i])<>0 then
                    if not(noAlphabat(copy(pg[i],pos(next_line[j],pg[i])+length(next_line[j]),length(pg[i])-pos(next_line[j],pg[i])-length(next_line[j])+1))) then
                        begin
                            t:=pos(next_line[j],pg[i])+length(next_line[j]);
                            Enterat(i,t);
                        end;
            i:=i+1;
        end;
    for i:=1 to long do
        while pg[i,1]=' ' do
            delete(pg[i],1,1);
    fillchar(full,sizeof(full),true);
    for i:=1 to long do
        if pg[i]='' then
            full[i]:=false;
    t:=0;
    for i:=1 to long do
        if full[i] then
            begin
                t:=t+1;
                pg[t]:=pg[i];
            end;
    for i:=t+1 to long do
        pg[i]:='';
    long:=t;
    for i:=1 to long do
        begin
            for j:=1 to key do
                if pos(key_word[j],pg[i])<>0 then
                    begin
                        pg_key[i]:=key_word[j];
                        break;
                    end;
            if pg_key[i]='' then
                pg_key[i]:='do';
        end;
    dfs(1,long,0);
    for i:=1 to long do
        kg[i]:=kg[i]*suojin;
    for i:=1 to long do
        writeln('':kg[i],pg[i]);
end.

比较坑爹的就是for循环嵌套无法处理,求大神帮修改

posted @ 2017-10-19 15:56  zhuchengyang  阅读(996)  评论(0编辑  收藏  举报