Пересмотрите Java / C / C ++ / и т. Д. код

10

Напишите программу, которая добавляет или удаляет пробелы для удобного форматирования кода. Правила того, как должен выглядеть код, когда вы закончите:

  • Ни одна строка не должна содержать более одного {и }.
  • A {всегда должен быть последним в строке.
  • A }всегда должно быть единственным в строке (кроме пробела, который стоит перед ним).
  • Количество пробелов перед каждой строкой должно быть фиксированным кратным текущего числа вложений. (Вы можете использовать любое количество отступов, если оно не изменится.)
  • Запрещается вставлять или удалять пробелы, которые не способствуют выполнению одного из этих правил.

Число вложений для первой строки равно 0. Число вложений любой другой строки - это число вложений предыдущей строки, плюс один, если предыдущая строка содержит a {, минус один, если текущая строка содержит a }.

{и }внутри строковые литералы и комментарии не учитываются в вышеуказанных правилах. Строковый литерал - это текст, заключенный в одинарные или двойные кавычки, где одинарные или двойные кавычки с нечетным числом обратных косых черт непосредственно перед ними не интерпретируются как конец строкового литерала. Комментарий является текст , заключенный в /*и */, или текст , идя от //конца линии. В строке несколько маркеров начала комментария, учитывается только первый. Комментарии не анализируются внутри строковых литералов.

Примеры

    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
источник
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Деннис

Ответы:

6

JavaScript (ES6), 376 373 378 393 байта

Это было ... довольно сложной задачей ...

Дайте мне знать, если что-то не так с выводом, хотя я не смог найти ничего, не могу найти больше ничего.

Неуправляемая версия

Я играл в код, как я написал, так что давайте посмотрим, как это происходит ...

ETHproductions
источник
выглядит хорошо для меня
tbodt
Я играл в гольф, когда писал, что означает, что вы настоящий гольфист ...
Эрик Игрок в гольф
4

JavaScript (ES6), 260 259 байт

Анализирует вход за символом. Использует отступ в 4 пространства.

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)

Это все еще WIP и был в основном проверен только против предоставленных примеров. Если вы нашли ошибку, пожалуйста, дайте мне знать в комментариях.

Состояние синтаксического анализатора полностью описывается следующими переменными:

  • d → текущая глубина вложения
  • i → флаг, указывающий, что мы находимся «внутри» кода (т.е. после начальных пробелов строки)
  • l → строка буквального флага
  • c → заблокировать комментарий
  • e → строка комментария

Обязательная версия с отступом

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
)

Контрольные примеры

Arnauld
источник