解析字符串对失败.坏脾气x3语法
Parsing pair of strings fails. Bad spirit x3 grammar
我想解析键值对,映射字符串到字符串。因为我想支持{ ... }
块的右手边,我想出了一个简单的语法开始
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/std_pair.hpp>
namespace grammar::map
{
using namespace boost::spirit::x3;
auto expression = rule<class expression, std::pair<std::string, std::string>>{"expression"};
auto lhs = *(~char_('='));
auto rest = *(~char_(';'));
auto block = '{' >> *expression >> '}';
auto expression_def = lhs >> '=' >> (block | rest) >> ';';
BOOST_SPIRIT_DEFINE(expression)
}
但是组合编译失败,除非我将表达式的属性改为std::string
//! Transform a string into a key-value map of strings.
template <class M, class R>
requires InputRange<R>() && _ContainerLike<M>
&& Same<value_type_t<M>, std::pair<const std::string, std::string>>()
// && Assignable<std::pair<std::string, std::string>, value_type_t<M>>()
M parse(R&& range)
{
auto begin = rng::begin(range);
auto end = rng::end(range);
auto map = M{};
auto ret = x3::phrase_parse(begin, end, *grammar::map::expression, x3::space, map);
if (!ret)
throw std::runtime_error{"parse error"};
return map;
}
我得到错误
boost/spirit/home/x3/support/traits/move_to.hpp:62:18: error: cannot convert ‘std::remove_reference<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&>::type {aka std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >}’ to ‘char’ in assignment
dest = std::move(src);
从 位于
boost/spirit/home/x3/support/traits/move_to.hpp: In instantiation of ‘void boost::spirit::x3::traits::detail::move_to_plain(Source&&, Dest&, mpl_::false_) [with Source = std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >; Dest = char; mpl_::false_ = mpl_::bool_<false>]’:
如果尝试下面的表达式
,也会发生同样的事情auto pair = std::pair<std::string, std::string>{};
auto ret = x3::phrase_parse(begin, end, grammar::map::expression, x3::space, map);
我从几天前就开始做这件事了,不知道该怎么做才好。我很感激任何帮助……: ^) 在boost-1.60{-62}和gcc 6.1.1、6.2以及较新版本的主干上进行了测试。
您的问题是您已经定义了expression
具有pair<string,string>
的属性,但lhs >> '=' >> (block|rest) >> ';'
的合成属性是synt_attr=tuple<string,variant<vector<synt_attr>,string>>
,基本上是synt_attr=pair<string,variant<map_of_value_type_synt_attr,string>>
。因此,根据您想要的结果,您至少有两个选项:
-
将合成属性更改为
pair<string,string>
。这是很容易使用x3::raw
指令(在WandBox上运行):auto expression_def = lhs >> '=' >> (raw[block] | rest) >> ';';
-
更改
expression
的定义,使其具有与合成属性兼容的属性。这需要使用递归变体,并且使您需要访问解析映射中的数据的方式变得复杂,因为您需要创建一个访问者(在WandBox上运行)。//A value is either a `string` or a `map<string,Value>` using Value = boost::make_recursive_variant<std::string,std::map<std::string,boost::recursive_variant_>>::type; ... struct printer : boost::static_visitor<void> { printer(int indent) :indent(indent) {} void operator()(const std::string& val) const { std::cout << std::string(indent, ' ') << val << std::endl; } void operator()(const std::map<std::string,Value>& val) const { for (const auto& pair : val) { std::cout << std::string(indent, ' ') << pair.first << ':' << std::endl; boost::apply_visitor(printer(indent + 4), pair.second); std::cout << std::string(indent, ' ') << std::endl; } } int indent; }; void print_map(const Value& val) { boost::apply_visitor(printer(0), val); }
相关文章:
- 这是实现图形的坏方法吗
- 提升精神 x3 - 懒惰解析器
- boost::spirit::x3 中的通用解析器生成器
- 增强精神 X3:错误:在"..."中没有名为"大小"的类型
- 提升精神 x3 解析为结构,如果它为空,则跳过成员
- 将树节点添加到向量向量中的 n 元树遍历的平均和最坏情况时间复杂度是多少?
- 如何处理Boost Spirit X3导致Visual Studio 2019 "static initialization order fiasco"?
- Boost Spirit X3:将(一些)空格解析为枚举
- Boost Spirit x3 条件(三元)运算符解析器
- 你如何从 Boost Spirit X3 词法解析器中获取字符串?
- 将 Boost.Spirit.X3 解析器拆分为多个 TU
- C++ - 最坏情况和平均情况插入时间复杂度在 std::unordered_map <int,int>?
- boost::spirit::x3 中的简单字符串解析器不起作用
- 解析为 x3::variant 时出现编译器错误
- 自定义预期失败的完整错误消息(boost::spirit::x3)
- wxWidgets mac剪贴板在3.1.3上坏了?
- 如何为 opencv 安装 gstreamer 1.0 坏插件?
- 计时器坏了或者其他什么的
- 提升精神 x3 错误处理程序与期望
- 解析字符串对失败.坏脾气x3语法