Reindent Java / C / C ++ / etc. código

10

Escreva um programa que adicione ou remova espaços em branco para formatar bem o código. Regras para a aparência do código quando você terminar:

  • Nenhuma linha deve conter mais de um de {e }.
  • A {sempre deve ser a última coisa em uma linha.
  • A }sempre deve ser a única coisa em uma linha (além do espaço em branco que vem antes dela).
  • A quantidade de espaço em branco na frente de cada linha deve ser um múltiplo fixo da contagem de aninhamento atual. (Você pode usar qualquer quantidade de recuo que desejar, desde que não seja alterado.)
  • Nenhum espaço em branco deve ser inserido ou removido que não contribua para satisfazer uma dessas regras.

A contagem de aninhamento para a primeira linha é 0. A contagem de aninhamento de qualquer outra linha é a contagem de aninhamento da linha anterior, mais uma se a linha anterior contiver a {, menos uma se a linha atual contiver a }.

{e }literais e comentários de strings internos não contam nas regras acima. Um literal de string é um texto entre aspas simples ou duplas, onde aspas simples ou duplas com um número ímpar de barras invertidas imediatamente antes delas não são interpretadas como o final da literal da string. Um comentário é um texto entre /*e */ou texto que vai do //final da linha. Em uma linha com vários marcadores de início de comentário, apenas o primeiro conta. Os comentários não são analisados ​​dentro de literais de string.

Exemplos

    main() {printf("Hello!"); // I don't care about the world...
        }

becomes:

main() {
    printf("Hello!"); // I don't care about the world...
}




int main(){
    puts("a");
        puts("b");
}

becomes:

int main(){
    puts("a");
    puts("b");
}


main()
{ printf("{"); /* }
} */
     printf("}//}"); ///*
    }

becomes:

main()
{
    printf("{"); /* }
} */
    printf("}//}"); ///*
}


int test[] = {1, 2, 3};

becomes:

int test[] = {
    1, 2, 3
}
;
tbodt
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Dennis

Respostas:

6

JavaScript (ES6), 376 373 378 393 bytes

Este foi ... um grande desafio ...

Deixe-me saber se há algo errado com a saída, embora eu não tenha encontrado nada e não possa encontrar mais nada.

Versão ungolfed

Joguei o código como escrevi, então vamos ver como isso acontece ...

ETHproductions
fonte
parece ser bom para mim #
23617 tbodt
I golfed o código como eu escrevi isso significa que você é um verdadeiro golfista ...
Erik o Outgolfer
4

JavaScript (ES6), 260 259 bytes

Analisa o caractere de entrada por caractere. Usa recuo de 4 espaços.

s=>s.replace(/[^]/g,(x,n)=>(p=s[n-1],a=!l&!c&!e,l|x!='/'?a&x=='*'&p=='/'?c=x:!c&!e&x=='"'?(l^=1,x):x==`
`?(i=e=0,x):a&x=='}'?d--&&i?`
`+x:i=x:a&x=='{'?s[i=!++d,n+1]==`
`?x:x+`
`:i?x:x==' '?'':' '.repeat(!c*d*4,i=1)+x:p==x?e=x:!e&p=='*'?(c=0,x):x),d=i=l=c=e=0)

Este ainda é um WIP e foi basicamente testado apenas nos exemplos fornecidos. Se você encontrar algum bug, entre em contato nos comentários.

O estado do analisador é totalmente descrito pelas seguintes variáveis:

  • d → profundidade atual de aninhamento
  • i → sinalizador informando que estamos localizados 'dentro' do código (ou seja, após os espaços iniciais da linha)
  • l → flag literal de string
  • c → bloquear comentário
  • e → sinalizador de comentário de linha

Versão recuada obrigatória

s => s.replace(
  /[^]/g,
  (x, n) => (
    p = s[n - 1],
    a = !l & !c & !e,
    l | x != '/' ?
      a & x == '*' & p == '/' ?
        c = x
      :
        !c & !e & x == '"' ?
          (l ^= 1, x)
        :
          x == `\n` ?
            (i = e = 0, x)
          :
            a & x == '}' ?
              d-- && i ? `\n` + x : i = x
            :
              a & x == '{' ?
                s[i = !++d, n + 1] == `\n` ? x : x + `\n`
              :
                i ?
                  x
                :
                  x == ' ' ? '' : ' '.repeat(!c * d * 4, i = 1) + x
    :
      p == x ?
        e = x
      :
        !e & p == '*' ? (c = 0, x) : x
  ),
  d = i = l = c = e = 0
)

Casos de teste

Arnauld
fonte