我试图获得一个qi :: rule<>根据boost employee示例发出带有BOOST_FUSION_ADAPT_STRUCT的结构。
我有以下结构及其相关的融合宏:
struct LineOnCommand
{
int lineNum;
std::vector<char> humpType;
};
BOOST_FUSION_ADAPT_STRUCT(
LineOnCommand,
(int, lineNum)
(std::vector<char>, humpType)
)
相关的解析规则是:
qi::rule<Iterator, std::vector<char> ascii::space_type> humpIdentifer = qi::lit("BH") | qi::lit("DH");
qi::rule<Iterator, LineOnCommand(), ascii::space_type> Cmd_LNON = qi::int_ >> -humpIdentifier >> qi::lit("LNON");
然后我有一个复合规则,其中所有其他规则(包括这个简单的测试用例)都是传递给解析器的部分:
qi::rule<Iterator, qi::unused_type, ascii::space_type> commands =
+( /* other rules | */ Cmd_LNON /*| other rules */);
bool success = qi::phrase_parse(StartIterator, EndIterator, commands, ascii::space);
当我尝试编译时出现问题,我收到错误:
<boostsource>/spirit/home/qi/detail/assign_to.hpp(152): error: no suitable constructor exists to convert form "const int" to "LineOnCommand"
attr = static_cast<Attribute>(val);
显然,我做错了什么,但我不确定是什么。如果我理解精神的工作方式,规则模板的第二个参数表示属性(即规则发出的数据类型),BOOST_FUSION_ADAPT_STRUCT宏将调整我的结构,以便boost知道如何转换流是&#34; int,std :: vector&#34;它。
我在这里做的和boost员工示例之间的唯一区别是我没有使用显式语法来进行解析。我的理解是,这不是必要的,而且规则本身就足够了。
我做错了什么?
答案 0 :(得分:2)
我不确定。我想我错过了这个问题。也许,我自然而然地#34;因为你的样本不是独立的,所以回避这个问题。
所以,我采取了以下措施:看到它Live On Coliru ,希望只是通过比较来帮助你:
我建议的不是qi::unused_type
;如果没有属性,则无需说明;除了迭代器类型之外,qi::rule
和qi::grammar
的模板参数不是位置。所以
qi::rule<It, qi::unused_type(), ascii::space_type> r;
qi::rule<It, ascii::space_type, qi::unused_type()> r;
qi::rule<It, ascii::space_type> r;
全部/逻辑/等效。
完整列表:
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct LineOnCommand
{
int lineNum;
std::vector<char> humpType;
};
BOOST_FUSION_ADAPT_STRUCT(
LineOnCommand,
(int, lineNum)
(std::vector<char>, humpType)
)
template <typename It, typename Skipper = ascii::space_type>
struct parser : qi::grammar<It, std::vector<LineOnCommand>(), Skipper>
{
parser() : parser::base_type(commands)
{
using namespace qi;
humpIdentifier = string("BH") | string("DH");
Cmd_LNON = int_ >> -humpIdentifier >> "LNON";
commands = +( /* other rules | */ Cmd_LNON /*| other rules */ );
}
private:
qi::rule<It, std::vector<char>(), Skipper> humpIdentifier;
qi::rule<It, LineOnCommand(), Skipper> Cmd_LNON;
qi::rule<It, std::vector<LineOnCommand>(), Skipper> commands;
};
int main()
{
typedef std::string::const_iterator Iterator;
parser<Iterator> p;
std::string const input =
"123 BH LNON\n"
"124 LNON\t\t\t"
"125 DH LNON\n"
"126 INVALID LNON";
auto f(input.begin()), l(input.end());
std::vector<LineOnCommand> data;
bool success = qi::phrase_parse(f, l, p, ascii::space, data);
std::cout << "success:" << std::boolalpha << success << ", "
<< "elements: " << data.size() << "\n";
if (success)
{
for (auto& el : data)
{
std::cout << "Item: " << el.lineNum << ", humpType '" << std::string(el.humpType.begin(), el.humpType.end()) << "'\n";
}
}
if (f!=l)
std::cout << "Trailing unparsed: '" << std::string(f,l) << "'\n";
return success? 0 : 1;
}
输出:
success:true, elements: 3
Item: 123, humpType 'BH'
Item: 124, humpType ''
Item: 125, humpType 'DH'
Trailing unparsed: '126 INVALID LNON'