Использование C # и регулярных выражений для анализа исходного кода и поиска вызовов функций с аргументами - PullRequest
2 голосов
/ 24 февраля 2009

У меня есть список вызовов функций, хранящихся в базе данных, и для некоторых вызовов функций меня интересуют аргументы вызова функции. Я анализирую исходный код C с моей программой (которая находится на C #). Я пытаюсь найти лучший способ получения вызовов функций с аргументами. Я прочитал исходный код в строку перед его синтаксическим анализом (чтобы я не использовал потоковый ридер в файле). Я попытался использовать некоторое регулярное выражение (что для меня несколько ново) для анализа исходного файла, но при использовании строки регулярного выражения получал больше, чем просто вызов функции: functionCall + ". * \\)"; (Я избегаю открытия (в вызове функции)

Вызовы функций хранятся в следующем формате в БД

Function Call
============
some_Call(

Существует причина, по которой они хранятся таким образом и не изменятся.

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

Дайте мне знать, если потребуется какое-либо разъяснение.

Ответы [ 3 ]

6 голосов
/ 24 февраля 2009

Частично причина, по которой ваше решение не удалось, состоит в том, что вы, вероятно, должны были использовать .*?) вместо жадного сопоставления.

Полный ответ должен следовать, по крайней мере, так:

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

functionCall("\")", ')')

Игнорировать скобки в комментариях (что можно сделать с помощью регулярного выражения)

functionCall(/*)*/ 1, // )
2)

Не подходите слишком часто (что вы можете сделать с помощью регулярных выражений)

functionCall(1) + functionCall(2) + (2 * 3) // Don't match past the first )

но он также должен игнорировать сбалансированные скобки

functionCall((1+(1))*(2+2))

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

(А технически вам придется работать с макросами, я могу представить

#define close_paren )

испортило бы ваш день ...)

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

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

Я написал быстрое регулярное выражение и проверил его, проверьте следующее:

            string tst = "some_function(type<whatever> tesxt_112,type<whatever> tesxt_113){";

        Regex r = new Regex(".*\\((.*)\\)");
        Match m = r.Match(tst);
        if (m.Success)
        {
            string[] arguments = m.Groups[1].Value.Split(',');
            for (int i = 0; i < arguments.Length; i++)
            {
                Console.WriteLine("Argument " + (i + 1) + " = " + arguments[i]);
            }
        }

        Console.ReadKey();

Таким образом, вывод для вышеуказанной строки будет:

Аргумент 1 = тип tesxt_112

Аргумент 2 = тип tesxt_113

Надеюсь, это поможет:

Андрей: -)

0 голосов
/ 24 февраля 2009

Не для того, чтобы унизить вас, но ... в Си, я (смутно) считаю, что вы можете сделать это:

void secondFunction() { /* no-op */ }

void firstFunction()
{
    void* xyz = secondFunction;

    xyz(); // this should call secondFunction
}

Это возможный сценарий? А как насчет других вариантов использования указателя?!?

Скажи, литьё по типу функционального стиля?!?

int a;
float b = float(a); // call to the "float" function?!? NO! it's a type casting

Использовать список предопределенных типов? Что если преобразование было в пользовательские структуры, а как насчет typedefs? Теперь вам тоже придется их разобрать!

Серьезно, используйте парсер !! доступно несколько опций , которые могут анализировать C.

Я думаю, что Regex - довольно плохой инструмент для работы.

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