PEG规则识别函数原型

2024-03-25

我正在尝试创建一个可以解析 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();” 输出是一个空字符串。我想得到函数原型。


好像');'本来应该 ”);”?

另外,因为你有一个船长(x3::space在通话中phrase_parse)这没有多大意义:

  • 还指定space在你的解析器表达式中(它永远不会匹配)
  • 不包裹nameRule里面一个lexeme or noskip指示。也可以看看提升精神船长问题 https://stackoverflow.com/questions/17072987/boost-spirit-skipper-issues/17073965#17073965

因此,首先要努力使其发挥作用:

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() (住在科里鲁 http://coliru.stacked-crooked.com/a/5343711408767b76).

我认为这基本上是由于您的 AS (std::string) 与语法不太相符。我想说看起来你的意思是“匹配”而不是“解析”,我会使用x3::raw暴露原始匹配:

Live On Colriu http://coliru.stacked-crooked.com/a/5bd37368dd5c7b3d

#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";
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PEG规则识别函数原型 的相关文章

随机推荐