Размышления о языке Си? - PullRequest
       19

Размышления о языке Си?

5 голосов
/ 08 сентября 2011

Название вопроса может вводить в заблуждение при чтении вне контекста.Позвольте мне сначала объяснить, что я пытаюсь построить.

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

  1. Объявили ли они переменную с именем 'x', это тип 'int' и т. Д.
  2. каково значение переменной 'z'?

Если бы это был какой-то скриптовый язык программирования, это могло бы быть намного проще.Я мог бы просто использовать include или eval, а затем сделать проверки.

Но когда дело доходит до программирования на С, я бы сказал, что это очень сложно.Как мне это сделать ?

Ответы [ 4 ]

2 голосов
/ 08 сентября 2011

Вы можете использовать ANTLR для этого. Уже есть грамматика C, которую вы можете использовать с ANTLR, поэтому в основном все, что вам нужно сделать, это передать код в antlr, а затем пройтись по дереву синтаксиса в поисках различных атрибутов ....

вы можете использовать ANTLR на нескольких языках. Хотя это может показаться пугающим на первый взгляд. На самом деле работать с ним удивительно легко.

1 голос
/ 08 сентября 2011

Я увидел инициативу по созданию дампа XML для дерева, созданного GCC, под названием gcc-xml .Таким образом, вы даете ему файл example1.cxx, например:

struct EmptyClass {};

int a_function(float f, EmptyClass e)
{
}

int main(void)
{
    return 0;
}

Вы получите обратно:

<?xml version="1.0"?>
<GCC_XML>
  <Namespace id="_1" name="::" members="_2 _3 _4 "/>
  <Function id="_2" name="main" returns="_5" context="_1" location="f0:8"/>
  <Function id="_3" name="a_function" returns="_5" context="_1" location="f0:4">
    <Argument name="f" type="_6"/>
    <Argument name="e" type="_4"/>
  </Function>
  <Struct id="_4" name="EmptyClass" context="_1" location="f0:1" members="_7 _8 " bases=""/>
  <FundamentalType id="_5" name="int"/>
  <FundamentalType id="_6" name="float"/>
  <Constructor id="_7" name="EmptyClass" context="_4" location="f0:1">
    <Argument name="_ctor_arg" type="_9"/>
  </Constructor>
  <Constructor id="_8" name="EmptyClass" context="_4" location="f0:1"/>
  <ReferenceType id="_9" type="_4c"/>
  <File id="f0" name="example1.cxx"/>
</GCC_XML>

Предостережения о том, что только работает с подмножеством Cсовместим с C ++ , а официальный проект не поддерживает создание дампов функций.Я не знаю, сколько прогресса сделали неофициальные усилия:

http://www.djlauk.de/index.php/Projects/GccXmlFunctionBodies

0 голосов
/ 08 сентября 2011

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

Способ анализа программы заключается в том, что агент понимает язык программирования извне и не имеет таких ограничений. Смотрите наш DMS Software Reengineering Toolkit для системы, которая может обеспечить максимальный контроль программы. Используя C Front End , вы, возможно, можете задать любой правильно сформулированный вопрос об исходном коде C. Надежным способом.

DMS и ее интерфейс C могут легко ответить на ваши конкретные вопросы (вопрос о значении Z может быть сложным; вы рассуждаете о машине Тьюринга).

0 голосов
/ 08 сентября 2011

Важным отличием является то, что вы подразумеваете под «проверкой» этих программ.Я предполагаю, что вы не имеете в виду на самом деле компилировать / запускать их во время выполнения (что для меня значит отражение), потому что вы не можете проверить их программную структуру из скомпилированной программы.

Это означает, что вы будете обрабатывать текстовые файлы исходного текста, и хотя это намного проще практически во всех языках сценариев, в C:

  1. * все не так плохо1006 * Узнайте, как получить список всех файлов для обработки.Либо поместите все имена файлов в индексный файл, итерируйте по этому файлу, ИЛИ получите список файлов, используя readdir или предпочтительно библиотеку (Boost), чтобы сделать это за вас.
  2. Для каждого файла откройте его и прочитайте каждую строку (Google, это тривиально)

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

  4. Сохранение результатов в массиве или запись в файл и т. Д.

Редактирование - если вы хотите проверить, есть ли программы ваших учениковвыполнить (иначе, скомпилировать / запустить их во время выполнения), вам, вероятно, потребуется execve отключить некоторые вызовы gcc (если вы хотите скомпилировать), а затем снова запустить программу.Тем не менее, execve сообщит вам только, если команда не выполнена.Получение выходных данных из других программ означало бы открытие каналов с popen.Если вы обнаружите, что готовы сделать это, поверните назад, вы зашли слишком далеко.

...