Как разобрать функцию и ее аргументы - PullRequest
2 голосов
/ 20 июля 2011

Для моего лексера я использую лексический итератор boost::wave, который выдает мне все токены из файла .cpp, .h .hpp и т. Д.

Теперь я хочу выяснить, является ли набор токенов, то есть идентификатор, за которым следует open parenthesis, а затем набор аргументов, разделенных comma и, наконец, closed parenthesis, функцией в программе на C ++.Я имею в виду, как я должен анализировать набор токенов, чтобы убедиться, что у меня есть функция?

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

Или есть функция (в boost::wave), которая может непосредственно анализировать функцию для меня?

Также было бы полезно, если кто-то может подсказать, как я могу найти переменную typeв аргументе функции.например, если у меня есть функция:

int myfun(char* c, T& t1) { //... }

, то как мне получить токены char и *, которые можно рассматривать как тип c.Точно так же токены T и &, которые можно рассматривать как тип t1?

РЕДАКТИРОВАТЬ: Вот немного больше объяснений к моему вопросу

ссылки:

документация волны поддержки

http://www.boost.org/doc/libs/1_47_0/libs/wave/index.html

список идентификаторов токенов

http://www.boost.org/doc/libs/1_47_0/libs/wave/doc/token_ids.html

typedef boost::wave::cpplexer::lex_token<> token_type;
typedef boost::wave::cpplexer::lex_iterator<token_type> token_iterator;
typedef token_type::position_type position_type;

position_type pos(filename);

//instr is the input file stream
token_iterator  it = token_iterator(instr.begin(), instr.end(), pos,
      boost::wave::language_support(
        boost::wave::support_cpp|boost::wave::support_option_long_long));
token_iterator  end = token_iterator();

//while it != end 
//...
boost::wave::token_id id = boost::wave::token_id(*it);

switch(id){
//...

    case boost::wave::T_IDENTIFIER:
      Match(id);//consumes one token and increments the token_iterator
        //get the token id of the next token       
      id = boost::wave::token_id(*it);
 //if an identifier is immediately followed by T_LEFTPAREN then it will be a function
      if(id == boost::wave::T_LEFTPAREN) {
        Match(id);                         (1)
        //this function i want to implement
        ParseFunction();                   (2) 
        Match(boost::wave::T_RIGHTPAREN);
      }
//...
}

Так что вопрос в том, как реализоватьфункция ParseFunction ()

1 Ответ

0 голосов
/ 20 июля 2011

Если ваша система совместима с POSIX (Linux, MacOSX, Solaris, ...), вы можете использовать dlopen / dlsym, чтобы определить, существует ли символ. Вам нужно остерегаться искажения имен, и в некоторых системах вам следует помнить, что [например] настоящее имя sin равно _sin.

Возвращает ли dlsym указатель на функцию или указатель на некоторую глобальную переменную & mdash; Dlsym не имеет понятия. Фактически, вам придется сделать что-то, что очень сильно противоречит стандартам C и C ++, чтобы использовать dlsym: вам придется привести указатель void*, возвращаемый dlsym, к указателю на функцию. Стандарт POSIX находится в конфликте с C / C ++. Тем не менее, если вы находитесь в POSIX-совместимой системе, эти void* указатели преобразуются в указатель на функцию (в противном случае система не POSIX-совместимая).


Edit:

Огромный гоча: Как вы называете то, что только что нашли? Как вы знаете, как обрабатывать возвращаемое значение, если оно есть?

Простой пример: предположим, что ваш входной файл содержит xsq = pow (x, 2). Вы должны заранее знать, что подпись pow является double pow (double, double).

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

...