JBFD: декомпилятор из Brainfuck в Java

    Кто-то когда-то сказал: «Возьмите несколько произвольных латинских букв, допишите перед ними J, и вы получите очередную Java-технологию». В этой статье речь пойдет о технологии JBFD, что означает Java BrainFuck Decompiler. Технология еще достаточно молодая (от силы 3 часа), так что не судите строго.

    Идея создания декомпилятора возникла не случайно. Всему виной большое количество статей по BrainFuck в Интернете вообще и на Хабре в частности. Интерпретаторов этого замечательного языка существует огромное множество, но вот средств для отладки BF кода мне удалось найти крайне мало.

    А что если преобразовать код с BF на свой «родной» язык и воспользоваться всеми преимуществами своей любимой IDE для обнаружения трудноуловимых ошибок, покрытия кода тестами, оптимизации и т.д.? Все это и много другое становится возможным с JBFD.

    Для нетерпеливых, ссылка на скачивание исходного кода декомпиляторя находится здесь — JBFD.java. Код работает на JDK версии 1.5 и выше.

    После компиляции JBFD.java и запуска программы без аргументов получаем:

    Usage: java JBFD <<filename>> <<options>>
    Options:
    	-p - just print cleaned up source code
    

    Опция -p не является обязательной. Может кому-то будет полезно для валидации кода и выкидывания из исходников переводов строк и комментариев. При валидации пока что обнаруживаются только лишние или недостающие символы ']' и '['. В случае с лишним ']' еще указывается номер строки и символа в исходном файле.

    Для примера попробуем декомпилировать простую echo.bf программу:

    ,+[-.,+]
    

    После выполнения команды 'java JBFD echo.bf' в текущей папке появится файл echo.bf.java со следующим содержимым:

    class Program {
        static class FuckedByte {
            char value;
    
            FuckedByte(int value) {
                this.value = (char) value;
            }
    
            char get() { return value; }
    
            void inc(int i) {
                value += i;
                value %= 256;
            }
            void dec(int i) {
                value -= i;
                value %= 256;
                if (value < 0)
                    value += 256;
            }
    
            static FuckedByte read() {
                try {
                    return new FuckedByte(System.in.read());
                } catch (Exception e) {
                    throw new RuntimeException("Error reading from System.in");
                }
            }
            void write() {
                System.out.print(value);
            }
        }
    
        public static void main(String[] args) {
            FuckedByte fb0 = new FuckedByte(0);
    
            fb0 = FuckedByte.read();
            fb0.inc(1);
            while (fb0.get() != 0) {
                fb0.dec(1);
                fb0.write();
                fb0 = FuckedByte.read();
                fb0.inc(1);
            }
    
        }
    }
    


    Содержимое метода main — это и есть декомпилированный код с Brainfuck, все остальное — для упрощения работы. Теперь файл можно компилировать, дебажить, покрывать тестами, обфусцировать, в общем делать с ним все, что позволяет вам ваше воображение.

    Декомпилятор тестировался пока что только на самых простых программах типа echo, hello world и т.д. Код декомпилятора писался на скорую руку и будет дорабатываться. Тем не менее уже сейчас буду благодарен за любые замечания и предложения по улучшению.

    Всем удачи.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 10
    • +4
      Может сделать наоборот? Java в BF?
      • 0
        Можно, но это будет намного сложнее реализовать. А зачем?
        • +1
          Интереснее же.
          • 0
            Challenge accepted. Дебаггер может быть тоже напишу…
            • 0
              Только вам придется либо разрабатывать собственный диалект брейнфака, либо урезать возможности брейнфаковой явы :)
          • +1
            Ну это же здорово! В Brainfuck'е всего восемь команд. Сделаем процессор, который умеет выполнять эти несчастные восемь команд и сможем кодить на Java под нашу супер-аппаратную платформу.
        • +1
          Идея достаточно интересная. Загитхабте :)
          • 0
            В таких случаях достойно и подобает заменять последовательности нескольких одинаковых +, -, > или < на одну операцию изменения соответствующей переменной — иначе код для средних по размеру BF-программ получается совершенно чудовищный.
            • 0
              Собственно в коде это и реализовано.
            • 0
              Когда я писал свою библиотеку для парсера, то в качестве одного из примеров использовал как раз BF. Декомпилятор в Python

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.