Boost 试图编译Spirit.Qi解析器的问题
下面是一个完全独立的示例。问题似乎是第84-89行-如果这些行被注释掉,那么示例将编译。我试图解析的是文件的每一行,其中有五个以冒号分隔的项,最后三个项是可选的。单个函数获取一个Boost 试图编译Spirit.Qi解析器的问题,boost,boost-spirit,boost-spirit-qi,boost-fusion,Boost,Boost Spirit,Boost Spirit Qi,Boost Fusion,下面是一个完全独立的示例。问题似乎是第84-89行-如果这些行被注释掉,那么示例将编译。我试图解析的是文件的每一行,其中有五个以冒号分隔的项,最后三个项是可选的。单个函数获取一个boost::filesystem::file,使用boost.interprocess将其吸入并解析 我希望它解析的示例: a:1 a:2:c a:3::d a:4:::e a:4:c:d:e 结果应该存储在向量中,并且文件行是一个包含五个成员的结构,最后三个是可选的。以下是代码和错误: 代码 我已经回答了Spirit
boost::filesystem::file
,使用boost.interprocess
将其吸入并解析
我希望它解析的示例:
a:1
a:2:c
a:3::d
a:4:::e
a:4:c:d:e
结果应该存储在向量中
,并且文件行
是一个包含五个成员的结构,最后三个是可选的。以下是代码和错误:
代码
我已经回答了Spirit邮件列表,但是为了完整起见,让我把它贴在这里
你的例子远非微不足道。我看不出您为什么在代码中留下进程间、文件系统或业力引用。这只会让每个愿意帮助的人都更难诊断。此外,在那里的某个地方有一个不匹配的括号。我假设您没有关闭
+(char-(':'| eol)
好的,让我们仔细看看。这是您的(简化)语法。它不再有用,但在属性方面,它的行为应该与原始语法相同:
*(+char_ >> -(*char_ >> (eol | -(*char_ >> (eol | -(':' >> +char_))))))
此语法的公开(传播属性)为:
vector<
tuple<
std::vector<char>,
optional<
tuple<
std::vector<char>,
variant<
char,
optional<
tuple<
std::vector<char>,
variant<
char,
optional<
std::vector<char>
>
>
>
>
>
>
>
>
>
漂亮吧
如果你进一步思考,你会意识到,写作
foo >> (eol | -bar) >> *eol
相当于:
foo >> -bar >> *eol
这使它更加简化:
rule<char const*, file_line()> f =
*eol >> e1 >> u >> -(':' >> e2 >> -(':' >> e2 >> -(':' >> e3) ) ) >> *eol;
或者b)使用语义操作来设置属性的元素(我会这么做)。我已经将其余的错误消息粘贴在这里,以防有人想看到:这就是Hartmut和Spirit都很棒的原因。非常感谢,我没想到会有这么简洁的答案。Hartmut在IRC上也给了我类似的东西,这解释了大量关于属性传播的工作原理:。这也解释了精神是多么的聪明。
rule<char const*, std::string()> e1 = +~char_(":\r\n");
rule<char const*, std::string()> e2 = *~char_(":\r\n");
rule<char const*, std::string()> e3 = +~char_("\r\n");
rule<char const*, ushort()> u = ':' >> ushort_;
rule<char const*, file_line()> fline =
*eol >> e1 >> u
>> -(':' >> e2 >> (eol | -(':' >> e2 >> (eol | -(':' >> e3))))) >> *eol;
*fline
foo >> (eol | -bar) >> *eol
foo >> -bar >> *eol
rule<char const*, file_line()> f =
*eol >> e1 >> u >> -(':' >> e2 >> -(':' >> e2 >> -(':' >> e3) ) ) >> *eol;
struct file_line
{
std::string a;
unsigned short b;
boost::optional<
fusion::vector<
std::string,
boost::optional<
fusion::vector<std::string, boost::optional<std::string> >
>
>
> c;
};