我有这个简单的解析器,用于解析VB样式的双引号字符串。因此,解析器应该转为类似
"This is a quoted string containing quotes ("" "")"
输入
This is a quoted string containing quotes (" ")
这是我为此提出的语法:
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'"';
}
};
但是,我得到的属性是单引号(“),而不是完整解析的消息。
答案 0 :(得分:4)
您可以在没有任何语义操作的情况下执行此操作:
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'"';
}
};
omit[]
指令仍然执行嵌入式解析器,但不公开任何属性,使得doubleQuote规则返回单个L'"'
。
答案 1 :(得分:1)
我认为你没有妥善保存结果:
doubleQuote[qi::_val = L'"']
在这里,由于'='符号,您可以覆盖已经存在的内容。请尝试使用'+ ='。
doubleQuote[qi::_val += L'"']
另外,我不知道保存是否是自动的,您可能必须在替代方案中的另一个解析器后添加相同的“+ =”:
(wide::char_ - L'"')[qi::_val += boost::spirit::arg_names::_1]
但我对Qi并不是那么好,所以也许它是自动化的,这是有道理的。
答案 2 :(得分:1)
好吧,我不完全确定原因,但我能够通过将分配操作移动到子规则来解决这个问题:
doubleQuote %= (wide::char_(L'"') >> L'"')[qi::_val = L'"'];
doubleQuote.name("double quote");
quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
quotedString.name("quoted string");
请注意operator %=
对doubleQuote的使用以及语义操作现在位于那里的事实。