这个简单的 boost::spirit::qi 解析器有什么问题?

发布于 2024-09-07 05:11:35 字数 894 浏览 14 评论 0原文

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

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

I've got this simple parser intended to parse VB style double quoted strings. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

來不及說愛妳 2024-09-14 05:11:35

您可以在没有任何语义操作的情况下完成此操作:

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

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

安静被遗忘 2024-09-14 05:11:35

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

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

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

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

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

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

但我对 Qi 不太擅长,所以也许它是自动的,这是有道理的。

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.

清醇 2024-09-14 05:11:35

好吧,我不完全确定为什么,但我能够通过将该赋值操作移动到子规则中来修复它:

doubleQuote %= (wide::char_(L'"') >> L'"')[qi::_val = L'"'];
doubleQuote.name("double quote");

quotedString = L'"' >> +(doubleQuote | (wide::char_ - L'"')) >> L'"';
quotedString.name("quoted string");

请注意 doubleQuote 的 operator %= 的使用以及语义操作的事实现在位于那里。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文