gpt4 book ai didi

c++ - 从逗号分隔的整数中解析 std::vector

转载 作者:太空宇宙 更新时间:2023-11-04 13:06:16 25 4
gpt4 key购买 nike

我正在尝试实现一个非常具体的语法,它要求我在某个时候解析逗号分隔的整数列表。 qi 规则如下所示:

qi::rule<Iterator, ascii::space_type> ident;
qi::rule<Iterator, ascii::space_type> nlist;

...

ident = char_ >> nlist;
nlist = ("(" >> int_ % "," >> ")");

...

我需要将值传递到 ident规则(表达式 ident 必须创建语法树节点,其中构造函数需要来自 nlist 的解析值)。我考虑过创建并填充 std::vector并使用像_val = vector<int>...这样的语义 Action .我现在不清楚的是如何根据此规则创建任意长度的 vector ,因为我没有对输入的长度做出任何假设,也没有使用像 examples 这样的预定义 vector 。 .

这是否可能,或者有更好的方法吗?

最佳答案

这就是灵气的生计。

只需使用任何兼容的属性类型和利润:

    using nlist_t = std::vector<int>;
using ident_t = std::pair<char, nlist_t>;

qi::rule<Iterator, ident_t(), qi::ascii::space_type> ident;
qi::rule<Iterator, nlist_t(), qi::ascii::space_type> nlist;

Note: For std::pair attribute compatibility, include the relevant fusion header:

Live On Coliru

#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

int main()
{
using nlist_t = std::vector<int>;
using ident_t = std::pair<char, nlist_t>;

using Iterator = std::string::const_iterator;
qi::rule<Iterator, ident_t(), qi::ascii::space_type> ident;
qi::rule<Iterator, nlist_t(), qi::ascii::space_type> nlist;

ident = qi::char_ >> nlist;
nlist = '(' >> qi::int_ % ',' >> ')';

for (std::string const input : { "a (1,2,3)", "+(881,-2,42) \n", "?(0)" }) {

ident_t data;
if (qi::phrase_parse(input.begin(), input.end(), ident, qi::ascii::space, data)) {
std::cout << "Parsed: " << data.first << "(";
for (auto i : data.second) std::cout << i << ",";
std::cout << ")\n";
} else
std::cout << "Parse failed: '" << input << "'\n";
}
}

打印

Parsed: a(1,2,3,)
Parsed: +(881,-2,42,)
Parsed: ?(0,)

奖金

使用 phoenix::construct 想象的 Ast 类型的版本:

Also Live On Coliru

#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;

namespace OoShinyAst {

using MyName = char;
using MyArgument = int;
using MyArgumentList = std::vector<MyArgument>;

struct MyIdent {
MyName name;
MyArgumentList args;

MyIdent() = default;
MyIdent(MyName name, MyArgumentList args)
: name(std::move(name)), args(std::move(args)) { }
};
}

int main()
{
using Iterator = std::string::const_iterator;
qi::rule<Iterator, OoShinyAst::MyIdent(), qi::ascii::space_type> ident;
qi::rule<Iterator, OoShinyAst::MyArgumentList(), qi::ascii::space_type> nlist;

nlist = '(' >> qi::int_ % ',' >> ')';
ident = (qi::char_ >> nlist) [ qi::_val = px::construct<OoShinyAst::MyIdent>(qi::_1, qi::_2) ];

for (std::string const input : { "a (1,2,3)", "+(881,-2,42) \n", "?(0)" }) {

OoShinyAst::MyIdent data;
if (qi::phrase_parse(input.begin(), input.end(), ident, qi::ascii::space, data)) {
std::cout << "Parsed: " << data.name << "(";
for (auto i : data.args) std::cout << i << ",";
std::cout << ")\n";
} else
std::cout << "Parse failed: '" << input << "'\n";
}
}

关于c++ - 从逗号分隔的整数中解析 std::vector<int>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42191747/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com