PEG规则识别功能原型

时间:2019-05-14 17:57:44

标签: c++ compiler-construction boost-spirit

我正在尝试创建一个可以解析C代码的解析器。我的用例分析可能包含函数原型的缓冲区。我想将此函数名称推送到符号表中。我是Spirit和PEG的新手,我试图弄清楚如何编写可以识别功能原型的规则。

这是我当前的实现方式:

auto nameRule = x3::alpha >> *x3::alnum;
auto fcnPrototypeRule = nameRule >> *nameRule;
auto fcnRule = fcnPrototypeRule >> space >> x3::char_('(') >> -(nameRule % ',') >> x3::char_(');');

这是我的应用程序代码:

class Parser {   

    public:
    std::string functionParser(const std::string& input) {
        std::string output;
        x3::phrase_parse(input.begin(), input.end(), fcnRule, space, output);
        return output;
    }
};

input is =“ extern void myFunction();” 输出为空字符串。我想获得函数原型。

1 个答案:

答案 0 :(得分:0)

看起来像');'应该是“);”?

此外,由于您有一个船长(对x3::space的呼叫中有phrase_parse),所以没有什么意义:

  • 还要在解析器表达式中指定space(永远不会匹配)
  • 请勿将nameRule包装在lexemenoskip指令中。另请参见Boost spirit skipper issues

首先要使它起作用:

std::string functionParser(const std::string& input) {
    namespace x3 = boost::spirit::x3;

    auto nameRule = x3::lexeme [x3::alpha >> *x3::alnum];
    auto fcnPrototypeRule = nameRule >> *nameRule;
    auto fcnRule = fcnPrototypeRule >> x3::char_('(') >> -(nameRule % ',') >> x3::char_(");");
    std::string output;
    x3::phrase_parse(input.begin(), input.end(), fcnRule, x3::space, output);
    return output;
}

但是,您会注意到它返回ndn() Live On Coliru )。

我认为这基本上是由于您的AS(std::string)与语法不太匹配所致。我想说的是您似乎要“匹配”而不是“解析”,而我会使用x3::raw公开原始匹配:

Live On Colriu

#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <iomanip>

std::string functionParser(const std::string& input) {
    namespace x3 = boost::spirit::x3;

    auto nameRule = x3::lexeme [x3::alpha >> *x3::alnum];
    auto fcnPrototypeRule = nameRule >> *nameRule;
    auto fcnRule = x3::raw[ fcnPrototypeRule >> '(' >> -(nameRule % ',') >> ')' >> ';' ];
    std::string output;
    x3::phrase_parse(input.begin(), input.end(), fcnRule, x3::space, output);
    return output;
}

int main() {
    for (auto s : {
        "extern void myFunction();",
        })
    {
        std::cout << std::quoted(s) << " -> " << std::quoted(functionParser(s)) << "\n";
    }
}