我正在尝试获取 qi::rule<> 以基于 boost 员工示例发出带有 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);
显然我做错了什么,但我不确定是什么。如果我理解 Spirit 的工作方式,规则模板的第二个参数表示属性(即规则发出的数据类型),并且 BOOST_FUSION_ADAPT_STRUCT 宏将调整我的结构,以便 boost 知道如何转换流“int,std::vector”。
我在这里所做的和 boost 员工示例之间的唯一区别是我没有使用显式语法来进行解析。我的理解是这没有必要,规则本身就足够了。
我做错了什么?
最佳答案
我不确定。我想我错过了这个问题。也许,我“自然地”回避了这个问题,因为你的样本不是独立的。
所以,这是我的看法:查看 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'
关于c++ - 将 boost::qi::rule 与 BOOST_FUSION_ADAPT_STRUCT 一起使用的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23276879/