Сведение CFG к структурированному коду - PullRequest
0 голосов
/ 15 января 2012

Я хотел бы сделать CFG для кода высокого уровня. Обычно это очень легко; пройтись по дереву, сделать каждый базовый блок по очереди, склеить его вместе с gotos.

К сожалению, gotos вышли из моды в наши дни, и большинство современных языков их не поддерживают. Поэтому мне нужен какой-то способ склеить мои основные блоки, используя только те операторы потока управления, которые существуют на языке: for, while, do ... while, if, break и continue. (Я не хочу рассматривать создание конечного автомата с использованием переменных.)

Может показаться, что, хотя для этого есть алгоритмы, они будут не работать в каждом случае. Таким образом, можно построить CFG, который не может быть сведен к структурированному коду, используя только вышеупомянутый ограниченный набор структур потока управления.

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

Я хотел бы знать, окончательно, возможно ли это или нет.

Вариант (а): есть ли у кого-нибудь пример CFG, который нельзя сплющить, как описано выше? (Что скажет мне, что это невозможно.)

Вариант (b): есть ли у кого-нибудь доказательства того, что CFG можно выровнять, как описано выше? (Это скажет мне, что это возможно возможно.) Алгоритм, чтобы сделать это, было бы также очень желательно, поскольку я тогда должен был бы заставить это работать ...

Ответы [ 3 ]

1 голос
/ 01 февраля 2012

Я думаю, что у меня есть результат.

Кажется, ответ: это невозможно.Это из Сообщения ACM , том 9, страницы 366–371 в статье 1966 года, под названием «Джузеппе Якопини» «Технологические схемы, машины Тьюринга и языки только с двумя правилами формирования». Ссылка CiteSeer. (На что, как ни странно, я нашел ссылку из оригинального Кнута (и, на мой взгляд, невероятно раздражающий) Перейти к утверждению, которое считается вредным .)

К сожалению, у них нет доказательств, говорящих о том, что они не смогли их найти.

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

1 голос
/ 12 июля 2017

хотя этот вопрос задавался давно, на самом деле это кажется возможным. У Mozilla была похожая проблема при компиляции LLVM в JS (или теперь WebAssembly). JS и WebAssembly разрешают только структурированный поток управления, в то время как LLVM допускает произвольный поток управления.

Они написали статью об этом, которая также используется для WebAssembly :

Эта идея смоделирована по алгоритму Relooper из 2011 . Там есть доказательство того, что любой поток управления может быть представлен в структурированном виде, используя только доступные конструкции потока управления в JavaScript, и используя вспомогательную переменную, такую ​​как label, упомянутую в семантике Tilt, без какого-либо дублирования кода (другие подходы разделяют узлы, и иметь плохие ситуации с размером кода в худшем случае). Переопределитель также был реализован в Emscripten, и за последние 4 года мы приобрели большой практический опыт, демонстрируя, что он дает хорошие результаты на практике, как правило, с небольшим использованием вспомогательной переменной.

0 голосов
/ 15 января 2012

В общем, вы не можете просто сплющить CFG, гуляя по дереву.Это будет работать для LL (k) грамматик, если у вас есть k прогнозных токенов.Однако для более сложных грамматик, таких как грамматики LR (k), требуются более сложные методы.См., Например, http://en.wikipedia.org/wiki/LR_parser.

. В общем, нет известного алгоритма, который анализирует ЛЮБОЙ CFG, хотя большинство полезных CFG можно записать в виде LR (k) грамматики.Дополнительные исследования улучшают это, и большие классы CFG могут быть проанализированы.Я не думаю, что проблема неразрешима (хотя я не уверен), поэтому, безусловно, возможно, что это всегда можно сделать, - но я думаю, что это проблема исследования, а не то, что ответят да / нет дляты здесь.

Я также должен добавить, что все стоящие сегодня языки являются тьюрингово-полными, что означает, что все, что вы можете сделать с GOTO, может быть сделано с конструкциями типа if / while / for / ....Новые языки - не ограничение, это теоретические строительные блоки, которые нуждаются в помощи.

На практике вы не сможете проанализировать любой CFG, который хотите.Но это не значит, что мы не будем знать, как в будущем ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...