2016-11-17 3 views
1

Учитывая произвольный исходный код C++, который содержит только определение одной функции, я пытаюсь захватить имя функции (которое может быть произвольным).Имя функции захвата

Для этого я предполагаю, что между именем функции и ее списком аргументов нет слов/слов, т. Е. Я ищу первое вхождение символа скобки «(» (который инициирует список аргументов функции) и захватить слово перед ним (из которого я думаю, что это имя функции); это правильное решение?

К сожалению, для меня непонятна спецификация C++ (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf стр. 207).

ответ

2

Я ищу первое вхождение символа скобки "(" который инициирует список аргументов функции ") и фиксирует перед ним слово (из которого я думаю, что это имя функции); это идет правильно

нет, это не правильно в самых основных случаях, это верно:.

int foo() { 
    return 1; 
} 

Но если вы хотите, чтобы поддержать любую функцию (нешаблонном), то в этом случае это не удастся:

std::function<int(int)> foo() { 
    return [](int) { return 1; }; 
} 

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

std::function< int (int) > foo() { 
    return [](int) { return 1; }; 
} 

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

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

Вы также можете указать указатели на функции, которые встроены в язык и разбить пробел + поиск в скобках ниже. Вам нужно будет построить анализатор :(

Для упрощения, вы можете запретить любые #include заявления, которые привели бы только основные функции, как и первый. Если это так, то вместо проверки для ( символа и получить слово раньше, почему бы не найти первый пробел и получить все между пробельных и (?

std::string get_function_name(std::string source) { 
    auto whitespace = source.find(' '); 
    if (whitespace == std::string::npos) 
     return ""; 

    auto open_bracket = source.find('(', whitespace); // find (after whitespace 
    if (open_bracket == std::string::npos) 
     return ""; 

    return source.substr(whitespace + 1, open_bracket - whitespace); 
} 

2

Возвратные типы функций могут быть очень странными, например.

void foo(int t){} 

void (* returnFptr())(int t){ 
    return foo; 
} 

Тип возврата returnFptr() является void(*)(int). Таким образом, первая открывающая скобка не гарантируется между именем функции и списком параметров.

Смежные вопросы