Как я могу сгенерировать Java CFG (Control Flow Graph), используя antlr? - PullRequest
2 голосов
/ 03 апреля 2012

Я пытаюсь проанализировать структуру кода Java.

Итак, я сгенерировал синтаксический анализатор Java и лексер, используя ANTLRv3 и код грамматики Java ...

но я не знаю, как я могу сгенерировать Graph Flow Graph, используя сгенерированный парсер и лексер.

Я пытался узнать, как это сделать, на странице учебника, но страница учебника уже исчезла.

Не могли бы вы дать мне способ, как это сделать? или учебная страница?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 03 апреля 2012

AFAIK, ANTLR не предоставляет никакой конкретной помощи в построении графика потока управления.

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

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

Вам потребуется создать узлы потока управления (просто разновидность класса), которые могут ссылаться на части AST («это действие») и на два других узла потока управления (для обработки if-then-else) ; это из этих выходов как «истинный выход» и «ложный выход» или, альтернативно, «продолжить» и «ловушка для» выходов. Подклассы этого будут представлять чистые вычисления, операторы IF, блоки TRY и т. Д.

Тот факт, что Java является чистым «структурированным» языком, означает, что вы можете построить график потока управления «снизу вверх»; вы можете создавать биты графика потока управления при обходе листа вверх и комбинировать графики потока управления от детей, когда вы взбираетесь на дерево. Что вам нужно сделать, это передать собранный до сих пор граф потока управления (изначально пустой на листьях) вверх по дереву со ссылкой на список узлов потока управления в этом графе, которые хотят передать управление обработчику исключений. Затем, поднимаясь по дереву, расширяйте график потока управления.

Большая часть работы выполняется на условном узле, таком как узел IF-THEN-ELSE; в этом случае два подграфа потока управления с двумя наборами исключений передаются на этот узел. Затем вы создаете узел потока управления для представления условного выражения, задаете его действие, указывающее на условное выражение, задаете его двум дочерним элементам указывать на два переданных подграфа и устанавливаете его исключение равным объединению набора исключений.

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

Точно так же относитесь к статуям THROW, хотя у них нет «следующего» действия.

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

Вам необходимо объединить предложения catch в последовательность операторов if.

Вы должны трактовать "finally" как вызов подпрограммы, вызванный из предложения try и различных предложений catch.

0 голосов
/ 18 апреля 2012

В эти дни я обнаружил подключаемый модуль Eclipse, генерирующий Java Flow Flow Graph: Factory Flow Graph Factory . Этот плагин прекрасно генерирует CFG и сохраняет его в виде файла XML.

...