1

我有这个简单的解析器,用于解析 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'"';
    }
};

但是,我得到的属性是一个单引号 ("),而不是完整的解析消息。

4

3 回答 3

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'"'.

于 2010-06-30T15:58:26.310 回答
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 %=for doubleQuote 的使用以及语义操作现在位于此处的事实。

于 2010-06-30T14:44:09.917 回答
1

我认为您没有正确保存结果:

doubleQuote[qi::_val = L'"']

在这里,由于 '=' 符号,您覆盖了已经存在的内容。尝试使用 '+=' 代替。

doubleQuote[qi::_val += L'"']

另外,我不知道保存是否是自动的,您可能必须在替代方案中的另一个解析器之后添加相同的“+=”:

(wide::char_ - L'"')[qi::_val += boost::spirit::arg_names::_1]

但我对 Qi 不太擅长,所以也许它是自动化的,这很有意义。

于 2010-06-30T06:51:22.140 回答