2010-06-30 121 views
1

我有这个简单的解析器,旨在解析VB风格双引号字符串。因此,解析器应该把类似这个简单的boost :: spirit :: qi解析器有什么问题?

"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'"'; 
    } 
}; 

不过,我的属性m得到的是单引号(“),而不是完整的解析消息。

回答

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[]指令仍然执行嵌入的解析器,但不公开任何属性,使得双引号规则返回单个L'"'

1

我想你不保存正确的结果:因为“=”号的

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

在这里,你会忘了已经与“+ =”尝试代替。

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

另外,我不知道,如果储蓄是自动的,你可能需要添加相同的“+ =”的替代其他分析器之后:

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

但我不认为与齐好,所以也许它是自动的,这是有道理的。

+0

除了'std :: wstring'没有从'wchar_t'分配成员的事实,这种情况才有意义... – 2010-06-30 13:29:12

+0

对,所以我很可能关闭了。 – 2010-06-30 13:51:03

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 %=和事实语义动作现在位于那里。

相关问题