0,0
рейтинг
25 марта 2011 в 05:37

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

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

Всем удачи.
Константин Чапюк @javenue
карма
21,0
рейтинг 0,0
Software Engineer

Самое читаемое Разработка

Комментарии (10)

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

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