我正在尝试解析并将此字符串"{ABC,HIJ}:{10,15,20}"
捕获到struct indicator_rec
中。
解析成功,但只有第一组{ABC,HIJ}
被捕获到std::vector<std::string>
字段中。
第二部分{10,15,20}
被正确解析,但无法进入第二个字段std::vector<unsigned>
。
我做错了什么?
输出:
<equation>
<try>{ABC,HIJ}:{10,15,20}</try>
<indicator>
<try>{ABC,HIJ}:{10,15,20}</try>
<fail/>
</indicator>
<indicators>
<try>{ABC,HIJ}:{10,15,20}</try>
<indicator>
<try>ABC,HIJ}:{10,15,20}</try>
<success>,HIJ}:{10,15,20}</success>
<attributes>[[A, B, C]]</attributes>
</indicator>
<indicator>
<try>HIJ}:{10,15,20}</try>
<success>}:{10,15,20}</success>
<attributes>[[H, I, J]]</attributes>
</indicator>
<success>:{10,15,20}</success>
<attributes>[[[A, B, C], [H, I, J]]]</attributes>
</indicators>
<parameters>
<try>{10,15,20}</try>
<parameter>
<try>10,15,20}</try>
<success>,15,20}</success>
<attributes>[]</attributes>
</parameter>
<parameter>
<try>15,20}</try>
<success>,20}</success>
<attributes>[]</attributes>
</parameter>
<parameter>
<try>20}</try>
<success>}</success>
<attributes>[]</attributes>
</parameter>
<success></success>
<attributes>[[]]</attributes>
</parameters>
<success></success>
<attributes>[[[[A, B, C], [H, I, J]], []]]</attributes>
</equation>
代码:
#define BOOST_SPIRIT_DEBUG
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/classic_symbols.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp> // std::regex not fully implemented in stdc++ yet
#include <string>
#include <map>
#include <utility>
#include <functional>
// -----------------------------------------------------------------------------
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace spirit = boost::spirit;
namespace phoenix = boost::phoenix;
// ---------------------------------------------------------------------------
struct indicator_rec
{
public:
indicator_rec() { }
std::vector<std::string> m_indicators;
std::vector<unsigned> m_parameters;
};
}
BOOST_FUSION_ADAPT_STRUCT(
client::indicator_rec,
(std::vector<std::string>, m_indicators)
(std::vector<unsigned>, m_parameters)
)
namespace client
{
// ---------------------------------------------------------------------------
template <typename Iterator>
struct system_parser :
qi::grammar<Iterator, ascii::space_type, indicator_rec()>
{
system_parser() :
system_parser::base_type(equation)
{
using qi::double_;
using qi::_val;
using qi::_1;
using boost::spirit::ascii::string;
equation %=
(indicator | indicators)
>> ':'
>> (parameters | parameter)
;
indicator %= (string("ABC")|string("HIJ"))
;
indicators %= '{' >> (indicator % ',') >> '}'
;
parameter %= qi::uint_
;
parameters %= '{' >> (parameter % ',') >> '}'
;
BOOST_SPIRIT_DEBUG_NODE(equation);
BOOST_SPIRIT_DEBUG_NODE(parameter);
BOOST_SPIRIT_DEBUG_NODE(parameters);
BOOST_SPIRIT_DEBUG_NODE(indicator);
BOOST_SPIRIT_DEBUG_NODE(indicators);
}
qi::rule<Iterator, ascii::space_type, indicator_rec()>
equation;
qi::rule<Iterator, ascii::space_type, std::vector<std::string>()>
indicators;
qi::rule<Iterator, ascii::space_type, std::string()>
designator, indicator;
qi::rule<Iterator, ascii::space_type, unsigned>
parameter;
qi::rule<Iterator, ascii::space_type, std::vector<unsigned>()>
parameters;
};
template <typename Iterator>
bool parse_system( Iterator first, Iterator last, client::indicator_rec& rec )
{
system_parser<Iterator> parser;
bool r = qi::phrase_parse( first, last, parser, ascii::space, rec );
if (first != last) // fail if we did not get a full match
return false;
return r;
}
template <typename Iterator>
bool parse_universe(Iterator first, Iterator last, std::vector<std::string>& v)
{
bool r = qi::phrase_parse(first, last,
// Begin grammar -------------------------------------
(
(+(qi::alpha|qi::char_( "_" ))) >> ':' >> '{' >>
(+~qi::char_(",}")) % ','
>> '}'
)
,
// End grammar ---------------------------------------
ascii::space, v);
if (first != last) // fail if we did not get a full match
return false;
return r;
}
}
main( int argc, char* argv[] )
{
std::string calculator( "{ABC,HIJ}:{10,15,20}" );
client::indicator_rec rec;
client::parse_system( calculator.begin(), calculator.end(), rec );
}
答案 0 :(得分:2)
因此,如果您不使用这些继承的属性,则必须在规则声明中使用rule_attribute_type()
。理想情况下,如果不这样做会导致编译器错误,但显然由于rule's template parameters的异构性质,很遗憾不会发生这种情况。