如何解析函数及其参数

How to parse a function and its arguments

本文关键字:参数 函数 何解析      更新时间:2023-10-16

对于我的词法分析器,我使用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()

如果您的系统是posix兼容的(Linux, MacOSX, Solaris,…),您可以使用dlopen/dlsym来确定符号是否存在。您需要注意名称混淆,并且在某些系统上,您需要注意[例如]sin的真实名称是_sin

dlsym返回的是指向函数的指针还是指向全局变量的指针—Dlsym毫无头绪。事实上,要使用dlsym,您必须做一些与C和c++标准非常相反的事情:您必须将dlsym返回的void*指针强制转换为函数指针。POSIX标准与C/c++有冲突。也就是说,如果您使用的是posix兼容的系统,那么这些void*指针将转换为函数指针(否则系统不兼容posix)。


编辑:

一个巨大的陷阱:你怎么称呼你刚刚发现的东西?您如何知道如何处理返回值,如果有的话?

一个简单的例子:假设您的输入文件包含xsq = pow (x, 2)。您必须提前知道pow的签名是double pow (double, double)

与使用dlsym相比,您最好处理您明确构建到解析器中的一组有限的函数。