使用容器将单个值解析为 ast 节点
parsing a single value into an ast node with a container
我的问题如下。我有一个 ast 节点,其定义如下:
struct foo_node{
std::vector<std::string> value;
}
我有一个像这样的解析器来解析结构,它工作正常:
typedef x3::rule<struct foo_node_class, foo_node> foo_node_type;
const foo_node_type foo_node = "foo_node";
auto const foo_node_def = "(" >> +x3::string("bar") >> ")";
现在我想实现解析器也解析 "bar"
,不带括号,但前提是它是单个条。我试着这样做:
auto const foo_node_def = x3::string("bar")
| "(" > +x3::string("bar") > ")";
但这给了我一个编译时错误,因为 x3::string("bar")
returns 是一个字符串而不是 std::vector<std::string>
。
我的问题是,如何实现 x3::string("bar")
解析器(以及 returns 字符串的所有其他解析器)解析为向量?
解析单个元素并将其暴露为单个元素容器属性的方法是x3::repeat(1) [ p ]
:
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
struct foo_node {
std::vector<std::string> value;
};
BOOST_FUSION_ADAPT_STRUCT(foo_node, value)
namespace rules {
auto const bar
= x3::string("bar");
auto const foo_node
= '(' >> +bar >> ')'
| x3::repeat(1) [ +bar ]
;
}
int main() {
for (std::string const input : {
"bar",
"(bar)",
"(barbar)",
})
{
auto f = input.begin(), l = input.end();
foo_node data;
bool ok = x3::parse(f, l, rules::foo_node, data);
if (ok) {
std::cout << "Parse success: " << data.value.size() << " elements\n";
} else {
std::cout << "Parse failed\n";
}
if (f != l)
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
版画
Parse success: 1 elements
Parse success: 1 elements
Parse success: 2 elements
我的问题如下。我有一个 ast 节点,其定义如下:
struct foo_node{
std::vector<std::string> value;
}
我有一个像这样的解析器来解析结构,它工作正常:
typedef x3::rule<struct foo_node_class, foo_node> foo_node_type;
const foo_node_type foo_node = "foo_node";
auto const foo_node_def = "(" >> +x3::string("bar") >> ")";
现在我想实现解析器也解析 "bar"
,不带括号,但前提是它是单个条。我试着这样做:
auto const foo_node_def = x3::string("bar")
| "(" > +x3::string("bar") > ")";
但这给了我一个编译时错误,因为 x3::string("bar")
returns 是一个字符串而不是 std::vector<std::string>
。
我的问题是,如何实现 x3::string("bar")
解析器(以及 returns 字符串的所有其他解析器)解析为向量?
解析单个元素并将其暴露为单个元素容器属性的方法是x3::repeat(1) [ p ]
:
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
struct foo_node {
std::vector<std::string> value;
};
BOOST_FUSION_ADAPT_STRUCT(foo_node, value)
namespace rules {
auto const bar
= x3::string("bar");
auto const foo_node
= '(' >> +bar >> ')'
| x3::repeat(1) [ +bar ]
;
}
int main() {
for (std::string const input : {
"bar",
"(bar)",
"(barbar)",
})
{
auto f = input.begin(), l = input.end();
foo_node data;
bool ok = x3::parse(f, l, rules::foo_node, data);
if (ok) {
std::cout << "Parse success: " << data.value.size() << " elements\n";
} else {
std::cout << "Parse failed\n";
}
if (f != l)
std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}
}
版画
Parse success: 1 elements
Parse success: 1 elements
Parse success: 2 elements