Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
null
. null
. null
, как если бы это был массив. null
, как если бы это был массив. null
как будто это было значение Throwable. Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null
.
Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html
Обычно CFGs вычисляются на представлении низшего уровня (например, байт-код JVM). Кто-то сделал тезис на таких вещах несколько лет назад. Мог бы быть полезный путь, описанный там для того, как достигнуть то представление.
, Так как Ваши входные и выходные языки являются тем же, нет никакого шага генерации кода - Вы уже сделаны! Однако теперь Вы добираетесь для обхода AST. В каждом узле AST необходимо спросить себя: действительно ли это - "переходящая" инструкция или нет? Вызовы метода и если операторы являются примерами переходящих инструкций. Так конструкции цикла (такой как for
и while
). Инструкции, такие как дополнение и умножение не переходят.
Первый партнер каждого оператора Java узел в CFG, наряду с узлом входа и выхода. Как первое приближение, обойдите дерево и:
Это даст Вам некоторый вид из CFG. Процедура является немного волосатой на шаге 2, потому что названный метод может быть объявлен в библиотеке, и не в другом месте в AST - если так, или не делает край или делает край к специальному узлу, представляющему запись в тот метод библиотеки.
это имеет смысл?
На основе некоторых комментариев это кажется, что OP действительно хочет сделать генерация кода - для преобразования AST в последовательность низшего уровня инструкций на основе точек перехода и базисных блоков.
Генерация кода является очень определенной для языка, и большая работа была помещена в эту тему. Прежде чем Вы сделаете генерацию кода, необходимо знать Ваш выходной язык - ли она быть ассемблером или просто некоторым другим высокоуровневым языком. Как только Вы определили это, просто необходимо обойти AST и генерировать последовательность инструкций, которая реализует код в AST. (Я говорю, что это просто, но это может быть твердо - трудно сделать вывод, потому что соображения здесь являются довольно определенными для языка.)
представление, которое Вы выбираете для генерации кода, будет содержать график потока управления, неявно или явно. Если Ваш выходной язык является довольно низким уровнем (близко к ассемблеру), то график потока управления должно быть относительно легко извлечь.
(Прокомментируйте, хотели ли бы Вы больше разъяснения.)
Вы когда-нибудь пробовали ANTLR Studio? Это уже не генерирует график AST дыры, но для обзора, его довольно полезный.
Когда я сделал это в прошлом, я использовал graphviz, в особенности точечный инструмент, для генерации графика. Я создал точечный входной файл путем фактического пересечения графика потока управления во время компиляции.
расположение Графика тяжелая проблема , и graphviz делает превосходное задание. Это может произвести к PS, PDF и различным форматам изображения, и расположение обычно довольно интуитивно для взгляда на. Я настоятельно рекомендую его.
Создание полного графа потока управления, который действительно учитывает весь язык проблемы сложнее, чем кажется. Вы не только должны определить, что кажется «базовыми блоками», но вы должны идентифицировать вызовы функций (вроде легко, но определить цель может быть сложнее), где могут происходить закулисные операции, такие как инициализаторы классов. и беспокоиться о точках, где могут возникнуть исключения и куда идет контроль, если возникает исключение.
Если вы внимательно изучите большинство языков, они также будут ясно о порядке вычисления вычислений в выражениях, и это важно, если у вас есть два побочных эффекта в выражении; поток управления должен отражать порядок (или неупорядоченность, если он не определен).
Возможно, вам нужна только абстракция потока управления с базовыми блоками и условными операторами. Это очевидно, немного проще.
В любом случае (простой CFG или полный CFG) вам нужно пройти AST, в каждой точке есть ссылка на возможные цели потока управления (например, для большинства случаев, таких как операторы IF, существуют две цели потока: предложения THEN и ELSE). На каждом узле свяжите этот узел с соответствующая цель потока управления, возможно, заменяющая цели потока (например, когда вы сталкиваетесь с IF).
Сделать это для полной семантики языка Java (или C) вполне много работы. Вы можете просто использовать инструмент, который вычисляет это с полки. См. http://www.semanticdesigns.com/Products/DMS/FlowAnalysis.html как это выглядит на самом деле, исходя из наших инструментов.