[Закрываются] интересные проекты компилятора

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

blockquote>

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.
blockquote>

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

26
задан Bill the Lizard 15 September 2012 в 23:19
поделиться

18 ответов

Если вас интересует оптимизация, может быть интересна векторизация циклов с использованием наборов команд SSE и MMX.

7
ответ дан shoosh 28 November 2019 в 06:23
поделиться

Я сделал это в своем собственном учении «когда». Я не стал бы уделять столько внимания оптимизации, как другим вещам, таким как вывод типов или JIT, байтовое кодирование или поддержка форматирования объектов / отладки.

Нет смысла концентрироваться на оптимизации, если вы также говорите, что это намного менее важно, чем думают люди. В коде имеет значение только то, что:

  • работает в узких циклах в нижней части стека вызовов (т. Е. Без вызова функций, явно или неявно)
  • фактически занимает значительный процент от время приложения (т. е. если код запускается редко, его оптимизация не сильно поможет).

Это довольно небольшая часть всего кода, который будет видеть компилятор.

Редактировать: К сожалению, я не могу избежать работы с компиляторами Фортрана, которые беспощадно шифруют код, делая его очень трудным для отладки, в то же время оказывая влияние эпсилон на производительность.

2
ответ дан Mike Dunlavey 28 November 2019 в 06:23
поделиться

Автоматическое поколение встроенного кода с помощью эвристических тестов для размера/скорости торгует offs.

1
ответ дан plinth 28 November 2019 в 06:23
поделиться

Другие интересные проекты могут включать в себя:

  • Добавление оптимизации хвостового вызова в Sun JVM с открытым исходным кодом.

  • Добавление оптимизации именованного возвращаемого значения (NRVO) к виртуальным машинам Python или Ruby.

  • Добавьте сборку регулярных выражений в виде байт-кода для вашей любимой цели (у .Net она уже есть. Я почти уверен, что у Java ее нет).

2
ответ дан benjismith 28 November 2019 в 06:23
поделиться

В то время как запись Вашего собственного языка является забавой и традиционным академическим действием, там уже существует слишком много плохо реализованных связанных с компилятором проектов. Кроме того, 8 недель недостаточно времени, чтобы сделать хорошее задание на полной реализации языка.

, Если Вы интересуетесь "чем-то связанным с оптимизацией", выбирают уже существующий язык или VM и оптимизируют его для производительности, размера или обоих. Это будет препятствовать тому, чтобы Вы имели для перестраивания всей реализации языка, позволяет Вам сфокусироваться на проблеме оптимизации, произведет продукт, полезный для других людей и не только другого академического осуществления, и может даже быть полезно в получении задания.

я верю интерпретатору байт-кода Попугая, и различные.Net синтаксические анализаторы Железного языка могли извлечь выгоду из даже простой оптимизации.

2
ответ дан Dour High Arch 28 November 2019 в 06:23
поделиться

Вы могли записать оптимизатор для IronScheme, поскольку он в настоящее время делает сладкий удар все, кроме нескольких 'внутренних' функций. :)

2
ответ дан leppie 28 November 2019 в 06:23
поделиться

Обнаружение петли и параметризованное развертывание должно быть достаточно сложным, чтобы сделать его интересным. Не очень сексуально, но слишком сексуально за 8 недель вас потонет.

2
ответ дан Paul Nathan 28 November 2019 в 06:23
поделиться

Вот другая идея..., хотя это все еще немного большое неопределенный:

Большая часть оптимизации сделана во время компиляции (кроме JIT-компиляторов, которые оптимизируют во времени выполнения). Но существует также много возможностей для оптимизации в разовом ссылкой и во время установки.

я особенно интересуюсь идеей платформы, где Вы не потрудились связываться до времени установки. Но во время того связывающего время установки процесса, Вы берете настойчиво стратегия оптимизации, так как Вы знаете большую подробную информацию об архитектуре машины и можете принять более тонкие и хорошо осведомленные решения оптимизации.

3
ответ дан benjismith 28 November 2019 в 06:23
поделиться

Компилятор Perl B :: CC выиграл бы от добавления и анализа типов. У меня просто нет времени для этого.

В последнее время было достаточно времени. http://blogs.perl.org/users/rurban/2011/02/use-types.html

0
ответ дан rurban 28 November 2019 в 06:23
поделиться

Изучите помощь проекту Сарая Кожи, который компилирует Python в C++. Я обдумываю лето, просьба о помощи была сделана. Определение способов улучшить компиляцию до C++ предоставило бы феноменальную оптимизацию программам Python!

http://code.google.com/p/shedskin/

4
ответ дан torial 28 November 2019 в 06:23
поделиться

В дополнение к предложениям «Книги Дракона» я также настоятельно рекомендую Стивена С. Мучника «Усовершенствованный дизайн и внедрение компилятора», который фокусируется на промежуточных представлениях, генерации кода и методах оптимизации.

4
ответ дан benjismith 28 November 2019 в 06:23
поделиться

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

4
ответ дан finnw 28 November 2019 в 06:23
поделиться

Однажды я написал язык программирования и виртуальную машину для его запуска. Язык был способен взаимодействовать с функциями, написанными специально для того, что содержалось в DLL (это было до автоматизации OLE) в 16-битной Windows.

Делая всю фронтальную вещь, я получил отличное понимание языка с обеих сторон. В то время я читал разные книги по компиляторам (например, печально известную книгу о Драконах), но она так и не запала, пока я не написал что-то конкретное. Теперь, спустя много лет, работа, которую я проделал, дала мне более высокую оценку и понимание таких вещей, как Java VM и CLR.

4
ответ дан Sean 28 November 2019 в 06:23
поделиться

Для изучения компиляторов, делая его от начала до конца лучшая идея. Используя простую машину бэкенда, НЕ x86, скорее выбирают некоторую простую машину как базовый MIPS. Я сделал свой проект компилятора старшекурсника предназначение для средства моделирования PDP-11, которое было большой целью, поскольку это сохранило вещи очень простыми. Благодаря некоторому примеру кода мы могли выполнить в простом компиляторе императивного языка приблизительно четыре недели. В C!

Сегодня, с мощными языками как ML, делая компилятор должно быть намного легче.

то, Что Вы делаете, должно действительно зависеть от того, в чем находится Ваш интерес. если это находится в оптимизации, найдите некоторую простую платформу, где это - все, чем необходимо коснуться себя.

я думаю, что самая плодотворная область сегодня добралась, чтобы быть в компиляции для потоковых целей или в своевременной компиляции.

5
ответ дан Ferruccio 28 November 2019 в 06:23
поделиться

Я думаю, пишущий, что мой собственный простой встроенный язык сценариев был одним из самого интересного связанного с компилятором проекта, который я сделал. Это преподавало мне каждый аспект процесса от дизайна до понятия, и так как я делал его с нуля, я мог сделать его столь простым или сложным, как мне было нужно, который позволил мне понимать понятия с большим количеством шума, то изменение установленного проекта могло бы иметь.

7
ответ дан Scott Dillman 28 November 2019 в 06:23
поделиться

Несколько лет назад я разработал DSL и записал компилятор для продукта, который произвела моя компания. DSL использовал нечетную комбинацию декларативных правил, событийно-ориентированной логики и композиционного наследования. Это был очень забавный проект, и я изучил много.

Это действительно возбудило мой интерес в синтаксических анализаторах & компиляторы, таким образом, я попытался не отставать от интересных новых разработок в технологии компилятора.

Относительно оптимизации, вот забавная статья, которую я прочитал в прошлом году:

http://theory.stanford.edu/~aiken/publications/papers/asplos06.pdf

В данной статье, авторы описывают технику для автоматического обнаружения локальных оптимизаций (превосходящий производительность нескольких популярных бэкендов компилятора C++) без эксперта, имеющего необходимость записать набор кода особого случая. Их техника использует алгоритмы обучения без учителя для обнаружения замен глазка высокого значения.

После чтения его, пришло в голову мне, что их подход мог быть увеличен путем предоставления алгоритму с "описанием машины", перечисляющим все инструкции (с их основными эффектами и их побочными эффектами) поддерживаемый целевой архитектурой процессора. Затем вместо того, чтобы использовать метод решения "в лоб" для нахождения эквивалентных последовательностей инструкции, решатель мог найти те последовательности намного более легко.

алгоритм машинного обучения все еще использовал бы эмпирические наблюдения для определения самой эффективной последовательности инструкций (потому что эффекты кэша, микрооперация в секунду, и конвейерно обрабатывающий почти требуют эмпирические данные синхронизации), но эквивалентность результата могла быть предсказана с помощью алгебраической программы автоматического доказательства теоремы, воздействуя на описание машины.

В газете, они говорят о том, как их оптимизаторы могли только обнаружить заменяющие последовательности глазка двух или трех инструкций (потому что иначе поиск "в лоб" займет слишком много времени и использует слишком много памяти). Помещение умного решателя в правильном месте в алгоритме могло позволить ему работать с более длинными заменяющими последовательностями.

Anyhoo... сообщают мне, когда Вы заканчиваете с тем проектом! И не забывайте упоминать меня в своем разделе "Acknowledgements"!!;-)

8
ответ дан benjismith 28 November 2019 в 06:23
поделиться

С 8-недельным таймфреймом вам нужно быть осторожным с «ползучестью». Это не слишком амбициозно, особенно если этот проект включает в себя другие аспекты построения компилятора (lexing / parsing) или если вы все еще изучаете инструменты (отладчик, yacc) и промежуточные структуры данных (DAG).

Тем не менее, моим первым предложением было бы попробовать некоторый Live Variable Analysis. Алгоритмы довольно хорошо проработаны, так что вам достаточно просто кодировать их в соответствии с вашими структурами данных и т. Д.

Это позволит вам сделать ограниченную форму удаления мертвого кода. То есть, если вы обнаружите, что переменная объявлена, но никогда не используется, не выделяйте для нее место. Если вы обнаружите, что значение установлено, но никогда не читается, не генерируйте набор.

Live Variable Analysis также может помочь с Распределением регистра, так что вы можете решить и это, если есть время, и вы сможете повторно использовать часть того, что вы собрали для удаления мертвого кода.

13
ответ дан GEOCHET 28 November 2019 в 06:23
поделиться

В моем классе компиляторов старшекурсника мы сначала записали рекурсивному спуску (нисходящий) синтаксический анализатор для подобного Паскалю языка с нуля: Лексический анализатор, синтаксический анализатор, все.

О на полпути в течение семестра, мы зеркально отразили к генераторам синтаксического анализатора/сканера как lex/yacc или гибкий провод/бизон. Мы создали компилятор, который возьмет наше подмножество Паскаля и скомпилирует его вниз в блок для стековой машины, которую нам дали (стековая машина uber простой, но принципы являются все еще тем же).

, Если Вы интересуетесь компиляторами, я не могу рекомендовать достаточно высоко Книга Дракона. Это предназначается, чтобы использоваться для 1 курса старшекурсника семестра и второй половины как курс уровня выпускника, и покрывает каждый бит теории и оптимизации, которой Вы могли когда-либо желать. Даже Joel нравится он . =)

Аплодисменты

4
ответ дан dmercer 28 November 2019 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: