PEG规则以识别功能原型

PEG rule to identify function protoype

本文关键字:功能 原型 识别 规则 PEG      更新时间:2023-10-16

我正在尝试创建一个可以解析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;
    }
};

输入为=" extern void myFunction((;"输出是一个空字符串。我想获得功能原型。

看起来');'应该是"(;"?

也有一个船长(呼叫phrase_parse中的x3::space(,这对:

没有多大意义。
  • 在解析器表达式中还指定space(它永远不会匹配(
  • 不要将nameRule包装在lexemenoskip指令中。另请参阅Boost Spirit Skipper问题

因此,首先刺入使它起作用:

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(与语法不太匹配的事实。我会说您的意思是"匹配"而不是" parse",我会使用x3::raw暴露原始匹配:

活在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";
    }
}