我有一个精神上的小解析器。问题在于属性规则。该规则应该能够同时解析
@ATTRIBUTE 数字 NUMERIC
@ATTRIBUTE 测试 {你好,世界}
typedef std::string::iterator string_iter_t;
qi::rule<string_iter_t, string()> ident_r= lexeme['"' >> +(char_("a-zA-Z0-9- ")) >> '"'] | lexeme[+char_("a-zA-Z0-9-")];
qi::rule<string_iter_t, string(), space_type> relation_rule =
no_case["@RELATION"] >> ident_r;
qi::rule<string_iter_t, optional<vector<string>>(), space_type> attr_val_rule =
no_case["NUMERIC"] |
('{' >> ident_r % ',' >> '}');
qi::rule<string_iter_t, tuple<string, optional<vector<string>>>(), space_type> attr_rule =
no_case["@ATTRIBUTE"] >> ident_r >> attr_val_rule;
当我尝试使用上面的代码进行编译时,我收到一个关于类型与最后一条规则不匹配的大编译错误。
当我将最后一条规则更改为读取时,错误消失了
qi::rule<string_iter_t, vector<string>(), space_type> attr_rule =
no_case["@ATTRIBUTE"] >> ident_r >> attr_val_rule;
但是当我尝试解析时出现运行时错误
@ATTRIBUTE 测试数字
由于未设置参数,因此触发了 boost::optional 中的断言。我得到以下
Assertion failed: this->is_initialized(), file c:\Libs\boost_1_52_0\boost/option
al/optional.hpp, line 630
谁能帮我理解我错过了什么?
我编译时遇到的错误
c:\Libs\boost_1_52_0\boost/spirit/home/qi/detail/assign_to.hpp(152) : error C244
0: 'static_cast' : cannot convert from 'const std::basic_string<_Elem,_Traits,_A
lloc>' to 'std::tuple<<unnamed-symbol>,_V0_t>'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Alloc=std::allocator<char>
]
and
[
<unnamed-symbol>=std::string,
_V0_t=boost::optional<std::vector<std::string>>
]
No constructor could take the source type, or constructor overload resol
ution was ambiguous
c:\Libs\boost_1_52_0\boost/spirit/home/qi/detail/assign_to.hpp(170) : se
e reference to function template instantiation 'void boost::spirit::traits::assi
gn_to_attribute_from_value<Attribute,T>::call<T>(const T_ &,Attribute &,boost::m
pl::false_)' being compiled
with
[
Attribute=std::tuple<std::string,boost::optional<std::vector<std::st
ring>>>,
T=std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,
T_=std::basic_string<char,std::char_traits<char>,std::allocator<char
>>
] ..... and goes on and on
我正在使用的程序的副本
int main(void)
{
using boost::trim_left;
using boost::istarts_with;
using boost::optional;
namespace qi = boost::spirit::qi;
using qi::no_case;
using qi::ascii::space;
using qi::char_;
using qi::lexeme;
using qi::ascii::space_type;
typedef std::string::iterator string_iter_t;
qi::rule<string_iter_t, string()> ident_r= lexeme['"' >> +(char_("a-zA-Z0-9- ")) >> '"'] | lexeme[+char_("a-zA-Z0-9-")];
qi::rule<string_iter_t, string(), space_type> relation_rule =
no_case["@RELATION"] >> ident_r;
qi::rule<string_iter_t, optional<vector<string>>(), space_type> attr_val_rule =
no_case["NUMERIC"] |
('{' >> ident_r % ',' >> '}');
qi::rule<string_iter_t, vector<string>(), space_type> attr_rule =
no_case["@ATTRIBUTE"] >> ident_r >> attr_val_rule;
string ss1 = "@ATTRIBUTE test NUMERIC";
vector<string> ans1;
bool ret1 = qi::phrase_parse(ss1.begin(), ss1.end(), attr_rule, space, ans1);
cout << boolalpha << ret1 << endl;
optional<vector<string>> ss;
string ss2 = "{hello, world}";
bool ret2 = qi::phrase_parse(ss2.begin(), ss2.end(), attr_val_rule, space, ss);
cout << ret2 << endl;
return 0;
}