Использование регулярного выражения Python для извлечения пространства имен из источников C ++ - PullRequest
1 голос
/ 15 июня 2009

Я пытаюсь извлечь пространства имен, определенные в файлах C ++.
В основном, если мой файл C ++ содержит:

namespace n1 {
  ...
  namespace n2 { ... } // end namespace n2 
  ...
  namespace n3 { ...} //end namespace n3 
  ...
} //end namespace n1

Я хочу получить: n1, n1 :: n2, n1 :: n3.

Есть ли у кого-нибудь предложения о том, как я могу это сделать с помощью python-regex?

Спасибо.

Ответы [ 6 ]

6 голосов
/ 15 июня 2009

Поиск имен пространства имен довольно прост с помощью регулярного выражения. Однако, чтобы определить уровень вложенности, вы должны будете отслеживать уровень вложенности фигурных скобок в исходном файле. Это проблема синтаксического анализа, которая не может быть решена (разумно) с помощью регулярных выражений. Кроме того, вам, возможно, придется иметь дело с любыми директивами препроцессора C в файле, которые могут определенно повлиять на синтаксический анализ.

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

2 голосов
/ 15 июня 2009

Необходимость настолько проста, что вам может не понадобиться сложный парсер. Вам необходимо:

  • извлечение имен пространства имен
  • считать открывающие / закрывающие фигурные скобки, чтобы отслеживать, где определено ваше пространство имен.

Этот простой подход работает, если выполняются другие условия:

  • вы не получаете ложного пространства имен, такого как строки внутри комментариев или внутри строк
  • вы не получите непревзойденных открывающих / закрывающих скобок внутри комментариев или строк

Я не думаю, что это слишком много спрашивает из вашего источника.

1 голос
/ 15 июня 2009

Вы могли бы написать базовый лексер для него. Это не так сложно.

1 голос
/ 15 июня 2009

Вы не можете полностью игнорировать директивы препроцессора, так как они могут вводить дополнительные пространства имен. Я видел много кода, как:

#define __NAMESPACE_SYSTEM__ namespace system

__NAMESPACE_SYSTEM__ {
   // actual code here...
}

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

0 голосов
/ 16 июня 2009

Это то, что я сделал ранее сегодня:

  • Извлечение комментария из файлов C ++
  • Используйте regex для извлечения определения пространства имен
  • Используйте простой поиск строки, чтобы получить открытые и закрытые позиции фигурных скобок

Добавленные различные проверки работоспособности показывают, что я успешно обрабатываю 99,925% своих файлов (5 сбоев из 6678 файлов). Проблемы возникают из-за несоответствия в числах {и}, вызываемого несколькими '{' или '}' в строках, и нечистого использования инструкции препроцессора.

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

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

Спасибо за ваши ответы.

0 голосов
/ 15 июня 2009

В большинстве случаев, когда кто-то спрашивает, как сделать что-то с регулярным выражением, он делает что-то очень неправильное. Я не думаю, что этот случай отличается.

Если вы хотите анализировать c ++, вам нужно использовать синтаксический анализатор c ++. Есть много вещей, которые можно сделать, чтобы победить регулярное выражение, но при этом быть действительными c ++.

...