Существуют ли какие-либо инструменты для анализа файла заголовка c и извлечения прототипа функции из файла заголовка c.

#c #parsing #code-generation

#c #Синтаксический анализ #генерация кода

Вопрос:

Особенно получение типа возвращаемой функции (и, если возможно, является ли это типом указателя).

(Я пытаюсь написать автоматическую генерацию библиотек-оболочек ioctl / dlsym (для LD_PRELOAD ed)). Предпочтительнее библиотека python или ruby, но приветствуется любое работоспособное решение.

Комментарии:

1. Doxygen способен генерировать XML-файлы, а IIRC тип возвращаемой функции сам по себе является полем. Если вы не получите более полезного ответа, вы можете исследовать это.

2. Как Doxygen узнает, был ли возвращаемый тип указателем, особенно если возвращаемый тип просто называл объявленный в другом месте typedef?

Ответ №1:

Я успешно использовал язык Haskells .C пакет из hackage (ответ Haskells на CPAN), чтобы сделать что-то подобное. Это предоставит вам полное дерево синтаксического анализа файла C (или заголовка), которое затем можно просмотреть для извлечения необходимой информации. Это должно AFAIK также работать с #include s #define s и так далее.

Боюсь, у меня не установлено соответствующее программное обеспечение для его тестирования, но это выглядело бы примерно так:

 handler (DeclEvent (Declaration d)) =
do
let (VarDecl varName declAttr t) = getVarDecl d
case t of 
     (FunctionType (FunType returnType params isVaradic attrs)) -> 
        do {- varName RETURNS returnType .... -}
         _ -> do return ()
    return ()
handler _ = 
    do return ()

main = do    
    let compiler = newGCC "gcc"
    ast <- parseCFile compiler Nothing opts cFileName
    case (runTrav newState (withExtDeclHandler (analyseAST ast) handler)) of
        ...
  

Вышесказанное может показаться пугающим, но вам, вероятно, не понадобится так много дополнительных строк Haskell, чтобы делать то, что вы хотите! Я с радостью поделюсь полным исходным кодом, который я использовал (~ 200 строк), если это может чем-либо помочь.

Комментарии:

1. Любая помощь в установке? cabal install language-c выдает «требуется cabal: happy, но его не удалось найти» даже после того, как cabal install happy работает.

2. Я пытаюсь использовать language.c для проекта прямо сейчас. Если у вас все еще есть полный исходный код для фрагмента в вашем ответе, это, вероятно, мне бы очень помогло.

3. @dohaqatar7: Вот так: pastebin.com/7ihKY0KV Я не предъявляю претензий к качеству. Это было написано в 2009 году для университетского задания, так что, вероятно, это не первоклассный haskell 🙂

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

Ответ №2:

cproto Программа делает это. Обратите внимание, что существуют две отдельные версии:

До недавнего времени GCC включал программу protoize , которая могла выполнять эту работу (и преобразовывать определения функций K amp; R в определения функций, созданные по ISO-прототипу); однако это больше не является частью дистрибутива GCC.

Ответ №3:

Похоже, что вы ищете способ легко сгенерировать абстрактное синтаксическое дерево произвольного кода на C. С этой целью (и если вы знакомы с python) я бы предложил использовать pycparser:

 parser = CParser()

buf = '''
  static void foo(int k)
  {
      j = p amp;amp; r || q;
      return j;
  }
'''

t = parser.parse(buf, 'x.c')
t.show()
  

генерирует:

 FileAST:
  FuncDef:
    Decl: foo, [], ['static']
      FuncDecl:
        ParamList:
          Decl: k, [], []
            TypeDecl: k, []
              IdentifierType: ['int']
        TypeDecl: foo, []
          IdentifierType: ['void']
    Compound:
      Assignment: =
        ID: j
        BinaryOp: ||
          BinaryOp: amp;amp;
            ID: p
            ID: r
          ID: q
      Return:
        ID: j
  

Каждый компилятор делает это, и большинство из них предоставляют API для доступа к своим различным процедурам синтаксического анализа / семантической проверки. Кроме того, любой часто используемый генератор синтаксического анализа должен иметь грамматики, доступные для синтаксического анализа c. Если вы обеспокоены производительностью и / или хотите остаться в c, я бы посоветовал взглянуть на:

  • clang: довольно полная реализация C на архитектуре llvm, поддерживающая большинство расширений gcc. Очень легко генерировать ASTS из кода C. Вы могли бы либо скомпилировать в clang как библиотеку и работать с ASTS напрямую, либо clang вывести их двоичный файл в стандартный вывод.
  • gcc (я бы лично выбрал clang; намного чище).
  • Antlr (Генератор синтаксического анализа; многие существующие решения для c распространяются по Интернету).

Ответ №4:

Наш инструментарий для реинжиниринга программного обеспечения DMS с его интерфейсом на C мог бы легко это сделать.

DMS использует определение языка (в данном случае языка C) для анализа исходного кода, построения деревьев синтаксического абстрагирования, определения типов выражений и построения полных таблиц символов. Он также может prettyprint возвращать ASTS обратно к допустимому тексту на языке (например, код C). Вы можете легко найти объявления функций и собрать все, что вы хотите, из записи таблицы символов для этого («является ли возвращаемый тип указателем?»), и / или распечатать объявление в качестве прототипа. Возможно, вам потребуется нормализовать символы, если вы хотите распечатать прототип, который фактически не зависит от других определений в реальном файле; для этого требуется создать AST для различных объявлений типов и заменить их друг в друге. В прошлом мы делали это для других клиентов, и это оборудование доступно во внешнем интерфейсе C.