Регулярные выражения с соответствующими скобками - PullRequest
1 голос
/ 13 февраля 2009

Я пытаюсь извлечь определенные жестко закодированные переменные из исходного кода C. Моя остающаяся проблема в том, что я хотел бы проанализировать инициализацию массива, например:

#define SOMEVAR { {T_X, {1, 2}}, {T_Y, {3, 4}} }

Достаточно разобрать этот пример на "{T_X, {1, 2}}" и "{T_Y, {3, 4}}", поскольку тогда можно выполнить рекурсию для получения полной структуры. Тем не менее, он должен быть достаточно общим, чтобы иметь возможность анализировать любые пользовательские типы.

Еще лучше был бы список регулярных выражений, которые можно использовать для дополнительных значений из общих конструкций кода C, таких как #define, перечисления и глобальные переменные.

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

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

РЕДАКТИРОВАТЬ: похоже, регулярные выражения не делают рекурсии или произвольно глубоких совпадений. Согласно здесь и здесь .

Ответы [ 7 ]

1 голос
/ 13 февраля 2009

Это регулярное выражение:

(\{\s*[A-Za-z_]+)\s*,\s*\{\s*\d+\s*,\s*\d+\s*\}\s*\}

кажется разумным, но я не знаю, достаточно ли это для вас. Он полон \ s *, чтобы разрешить произвольный пробел между токенами, с точки зрения C, который допустим. Это будет соответствовать вещам, которые выглядят более или менее просто вашими примерами; какой-то идентификатор, за которым следуют ровно две цифры.

1 голос
/ 13 февраля 2009

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

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

1 голос
/ 13 февраля 2009

РЕДАКТИРОВАТЬ: Теперь, когда вопрос был обновлен, кажется, что мой предыдущий ответ не прошел. Я не знаю, если вы уже искали другие вопросы, связанные с регулярными выражениями в переполнении стека. По вероятности, что у вас нет, я натолкнулся на два, которые могут помочь вам дать представление о вашей проблеме (которая, по крайней мере, частично, является проблемой попытки сопоставления и отслеживания открытия и закрытия фигурных скобок): это и это . Удачи!

1 голос
/ 13 февраля 2009

Я предполагаю, что у вас есть доступ к рассматриваемому коду C. Если это так, то определите два макроса:

#define BEGIN_MATLAB_DATA
#define END_MATLAB_DATA

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

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

1 голос
/ 13 февраля 2009

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

Это может быть легко использовано для глобальных переменных, но #defines обрабатывается препроцессором, поэтому я не уверен, как они будут работать.

cristi:tmp diciu$ cat test.c
#define t 1
int m=5;


int fun(char * y)
{
    float g;

    return t;
}

int main()
{
    int g=7;
    return t;
}


cristi:tmp diciu$ ~/Downloads/checker-137/clang -ast-dump test.c
(CompoundStmt 0xc01ec0 <test.c:6:1, line:10:1>
  (DeclStmt 0xc01e70 <line:7:2>
    0xc01e30 "float g"
  (ReturnStmt 0xc01eb0 <line:9:2, line:1:11>
        (IntegerLiteral 0xc01e90 <col:11> 'int' 1)))
(CompoundStmt 0xc020a0 <test.c:13:1, line:16:1>
  (DeclStmt 0xc02060 <line:14:2>
    0xc02010 "int g =
      (IntegerLiteral 0xc02040 <col:8> 'int' 7)"
  (ReturnStmt 0xc01b50 <line:15:2, line:1:11>
    (IntegerLiteral 0xc02080 <col:11> 'int' 1)))
typedef char *__builtin_va_list;
Read top-level variable decl: 'm'

int fun(char *y)


int main()
1 голос
/ 13 февраля 2009

Может быть, файл синтаксиса vim поможет в этом вопросе. Я не уверен, есть ли в нем те элементы, которые вы ищете (я не делаю C), но в нем много элементов, так что это определенно отправная точка. Скачайте vim (www.vim.org) и в vim / syntax / c.vim немного осмотрите.

1 голос
/ 13 февраля 2009

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

http://www.regular -expressions.info /

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