Réindentez Java / C / C ++ / etc. code

10

Écrivez un programme qui ajoute ou supprime des espaces pour bien formater le code. Règles à quoi le code devrait ressembler lorsque vous avez terminé:

  • Aucune ligne ne doit contenir plus d'un {et }.
  • Un {devrait toujours être la dernière chose sur une ligne.
  • Un }devrait toujours être la seule chose sur une ligne (en plus des espaces qui le précèdent).
  • La quantité d'espaces devant chaque ligne doit être un multiple fixe du nombre d'imbrication actuel. (Vous pouvez utiliser la quantité d'indentation que vous souhaitez, tant qu'elle ne change pas.)
  • Aucun espace ne doit être inséré ou supprimé qui ne contribue pas à satisfaire à l'une de ces règles.

Le nombre d'imbrication pour la première ligne est 0. Le nombre d'imbrication de toute autre ligne est le nombre d'imbrication de la ligne précédente, plus un si la ligne précédente contient un {, moins un si la ligne actuelle contient un }.

{et }les littéraux de chaîne et les commentaires ne comptent pas dans les règles ci-dessus. Un littéral de chaîne est du texte entre guillemets simples ou doubles, où les guillemets simples ou doubles avec un nombre impair de barres obliques inverses immédiatement avant ne sont pas interprétés comme la fin du littéral de chaîne. Un commentaire est un texte placé entre /*et */, ou un texte allant de //la fin de la ligne. Dans une ligne, plusieurs marqueurs de début de commentaire, seul le premier compte. Les commentaires ne sont pas analysés à l'intérieur des littéraux de chaîne.

Exemples

    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
la source
Les commentaires ne sont pas pour une discussion approfondie; cette conversation a été déplacée vers le chat .
Dennis

Réponses:

6

JavaScript (ES6), 376 373 378 393 octets

C'était ... tout le défi ...

Faites-moi savoir s'il y a quelque chose qui ne va pas avec la sortie, bien que je ne trouve rien , je ne trouve rien de plus.

Version non golfée

J'ai joué au code tel que je l'ai écrit, alors voyons comment ça se passe ...

ETHproductions
la source
me semble bien
tbodt
J'ai joué au code en l'écrivant, ce qui signifie que vous êtes un vrai golfeur ...
Erik the Outgolfer
4

JavaScript (ES6), 260 259 octets

Analyse le caractère saisi caractère par caractère. Utilise une indentation de 4 espaces.

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)

Il s'agit toujours d'un WIP et a été essentiellement testé uniquement par rapport aux exemples fournis. Si vous trouvez un bug, faites-le moi savoir dans les commentaires.

L'état de l'analyseur est entièrement décrit par les variables suivantes:

  • d → profondeur d'imbrication actuelle
  • i → drapeau indiquant que nous sommes situés "à l'intérieur" du code (c'est-à-dire après les premiers espaces de la ligne)
  • l → drapeau littéral de chaîne
  • c → drapeau de commentaire de bloc
  • e → indicateur de commentaire de ligne

Version en retrait obligatoire

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
)

Cas de test

Arnauld
la source