使用提升::精神::qi 重新合成中间值
Resynthesize intermediate values with boost::spirit::qi
给定一个合成用户定义类型的语法,我如何编写另一个语法:
- 重用第一种语法。
- 使用第一个类型的基础值合成第二个不同的类型?
在下面的示例中,我按照 Boost Spirit 文档创建了一个解析器,foo_parser
,它合成了一个 foo_struct
类型的值。我想编写第二个解析器,bar_parser
,它重用foo_parser
但合成了不同(但明显相似)的 bar_struct
型值。我天真的例子,注释掉了,引起了壮观的 g++ 烟花。:)
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
namespace s {
using namespace boost::spirit;
using namespace boost::spirit::qi;
using namespace boost::spirit::ascii;
}
struct foo_struct {
int i;
char c;
};
BOOST_FUSION_ADAPT_STRUCT(
foo_struct,
(int, i)
(char, c)
)
struct bar_struct {
int i;
char c;
int j;
};
template <typename Iterator>
struct foo_parser : s::grammar<Iterator, foo_struct()>
{
foo_parser() : foo_parser::base_type(start) {
start %= s::int_ >> s::char_ ;
}
s::rule<Iterator, foo_struct()> start;
};
/*
BOOST_FUSION_ADAPT_STRUCT(
bar_struct,
(int, i)
(char, c)
(int, j)
)
template <typename Iterator>
struct bar_parser : s::grammar<Iterator, bar_struct()>
{
bar_parser() : bar_parser::base_type(start) {
// reuse a foo_parser
start %= foo >> s::int_ ;
}
foo_parser<Iterator> foo;
s::rule<Iterator, bar_struct()> start;
};
*/
我以前设计过这个 - 有点 - 笨拙的方式来解决问题
struct mybase { int a,b; };
struct myderived : mybase
{
mybase& base;
int c,d;
myderived() : base(*this) { }
};
BOOST_FUSION_ADAPT_STRUCT(mybase, (int,a)(int,b));
BOOST_FUSION_ADAPT_STRUCT(myderived, (mybase,base)(int,c)(int,d));
我更喜欢基于BOOST_FUSION_ADAPT_ADT的解决方案,但我无法让它工作,另请参阅[spirit-general]邮件列表:
- http://boost.2283326.n4.nabble.com/struct-derived-struct-fusion-adapted-and-the-sequence-operator-td4259090.html
- 或在列表中搜索
derived base
以下是其中的完整示例:
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted.hpp>
struct mybase { int a,b; };
struct myderived : mybase {
myderived() : base(*this) { }
mybase& base;
int c,d;
};
BOOST_FUSION_ADAPT_STRUCT(mybase, (int,a)(int,b));
BOOST_FUSION_ADAPT_STRUCT(myderived, (mybase,base)(int,c)(int,d));
int main()
{
using namespace boost::spirit::qi;
const char input[] = "1 2 3 4";
const char *f(input), *l(f+strlen(input));
rule<const char*, mybase() , space_type> base_ = int_ >> int_;
rule<const char*, myderived(), space_type> derived_ = base_ >> int_ >> int_;
myderived data;
bool ok = phrase_parse(f,l,derived_,space,data);
if (ok) std::cout << "data: " << data.a << ", " << data.b << ", " << data.c << ", " << data.d << "n";
else std::cerr << "whoopsn";
if (f!=l)
std::cerr << "left: '" << std::string(f,l) << std::endl;
return 0;
}
输出:
data: 1, 2, 3, 4
相关文章:
- 2D数组来自文本输入,中间有空格
- 递归形成字符串中所有数字字符的中间和?
- 链表错误的中间
- 在 boost::qi 中使用过多的替代运算符会导致分段错误
- 提升精神 V2 Qi 语法线程安全吗?
- 如何在 qi 符号表中使用 std::function
- 使(虚拟)函数在大多数派生类中无法访问中间基类中可访问,定义良好?
- 从函数返回范围视图时,带有std::span:中间对象所有权的C++Ranges-v3
- 如何输入数组的元素,每次获得新元素时,我们将其放在数组的中间?
- 查找中间两个数字的正则表达式的匹配项
- 解析为带有 qi 和替代部分的结构
- 如何在 boost::spirit::qi 中将某些语义操作排除在 AST 之外
- 我可以擦除 std::queue 中间的节点吗?
- 如何在标准c ++中流式传输/读取二进制文件的中间部分并写入另一个文件?
- 如何在 FOR 语句中间阻止 Visual Studio 2017 c++ 自动完成)?
- 给定类型的模板化中间数组
- 提升精神 QI:在元组上自动规则演绎,在替代函数中带有序列
- 如何在文本文件中间插入字符
- 如何组合一个宽字符字符串,中间插入一些空字符
- 使用提升::精神::qi 重新合成中间值