[英]What is the problem with this simple boost::spirit::qi parser?
I've got this simple parser intended to parse VB style double quoted strings. 我有这个简单的解析器,用于解析VB样式双引号字符串。 Thus, the parser should turn something like
因此,解析器应该将类似
"This is a quoted string containing quotes ("" "")"
into an output of 变成
This is a quoted string containing quotes (" ")
Here is the grammar I came up with for this: 这是我为此想到的语法:
namespace qi = boost::spirit::qi;
namespace wide = qi::standard_wide;
class ConfigurationParser : public qi::grammar<std::wstring::iterator, std::wstring()>
{
qi::rule<std::wstring::iterator, std::wstring()> quotedString;
qi::rule<std::wstring::iterator> doubleQuote;
public:
ConfigurationParser() : ConfigurationParser::base_type(quotedString, "vFind Command Line")
{
doubleQuote = (wide::char_(L'"') >> wide::char_(L'"'));
quotedString = L'"' >> +(doubleQuote[qi::_val = L'"'] | (wide::char_ - L'"'))>> L'"';
}
};
However, the attribute I'm getting is a single quote mark ("), rather than the full parsed message. 但是,我得到的属性是单引号(“),而不是完整的解析消息。
You can do it without any semantic actions: 您可以执行此操作而无需任何语义动作:
class ConfigurationParser
: public qi::grammar<std::wstring::iterator, std::wstring()>
{
qi::rule<std::wstring::iterator, std::wstring()> quotedString;
qi::rule<std::wstring::iterator, wchar_t()> doubleQuote;
public:
ConfigurationParser()
: ConfigurationParser::base_type(quotedString, "vFind Command Line")
{
doubleQuote = wide::char_(L'"') >> omit[wide::char_(L'"')];
quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
}
};
The omit[]
directive still executes the embedded parser but doesn't expose any attribute, making the doubleQuote rule return a single L'"'
. omit[]
指令仍执行嵌入式解析器,但不公开任何属性,从而使doubleQuote规则返回单个L'"'
。
I think you don't save the result properly: 我认为您没有正确保存结果:
doubleQuote[qi::_val = L'"']
Here, because of the '=' sign, you override what was already in. Try with '+=' instead. 在这里,由于有'='符号,您将覆盖已存在的内容。请改用'+ ='。
doubleQuote[qi::_val += L'"']
Also, I don't know if saving is automatic, you may have to add the same '+=' after the other parser in the alternative: 另外,我不知道保存是否是自动的,您可能必须在另一个解析器之后添加相同的“ + =”:
(wide::char_ - L'"')[qi::_val += boost::spirit::arg_names::_1]
But I am not that good with Qi so perhaps it IS automated, which would make sense. 但是我对Qi并不满意,所以也许它是自动化的,这很有意义。
Well, I'm not entirely sure why, but I was able to fix it by moving that assignment action into the sub rule: 好吧,我不确定为什么,但是我可以通过将赋值操作移到子规则中来解决它:
doubleQuote %= (wide::char_(L'"') >> L'"')[qi::_val = L'"'];
doubleQuote.name("double quote");
quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
quotedString.name("quoted string");
Note the use of operator %=
for doubleQuote and the fact that the semantic action is now located there. 注意,对doubleQuote使用了
operator %=
,并且语义动作现在位于该位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.