【问题标题】:How to capture character without consuming it in boost::spirit::qi如何在 boost::spirit::qi 中捕获字符而不消耗它
【发布时间】:2013-02-13 15:07:30
【问题描述】:

我正在使用boost::spirit::qi 来解析看起来像这样的“模板”格式:

/path/to/:somewhere:/nifty.json

其中:somewhere: 表示由名称somewhere 标识的任何字符串(名称可以是两个: 字符之间的任何一系列字符)。我有一个可用的解析器,但我想再做一个改进。

我想知道:somewhere: 占位符后面的字符(在本例中为/)。但是我的解析器的其余部分仍然需要知道这个/ 并在下一节中使用它。

如何在:somewhere: 之后“读取”/ 而无需实际使用它,以便解析器的其余部分可以看到并使用它。

【问题讨论】:

  • “我有一个可用的解析器”(不幸的是,这个边距太小而无法包含它?)

标签: c++ boost boost-spirit boost-spirit-qi


【解决方案1】:

你正在寻找

例子:

 myrule = lexeme [ *~char_(":") ] >> ":" >>
       (  (&lit('/') >> absolute_path)
        | (relative_path)
       )

【讨论】:

    【解决方案2】:

    正如他所说,这可以使用lookahead parser operator & 来完成,但如果您还想发出字符,还需要boost.phoenixqi::localsqi::attr

    例如:

    #include <boost/fusion/include/std_pair.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    #include <boost/spirit/include/qi.hpp>
    
    #include <iostream>
    #include <string>
    
    namespace qi = boost::spirit::qi;
    
    int main(int argc, char** argv)
    {
        std::string input("foo:/bar");
        std::pair<char, std::string> output;
    
        std::string::const_iterator begin = input.begin(),
                                    end = input.end();
    
        qi::rule<std::string::const_iterator, qi::locals<char>, std::pair<char, std::string>()> duplicate =
              "foo"
           >> qi::omit[
                 &(":" >> qi::char_[qi::_a = qi::_1])
              ]
           >> qi::attr(qi::_a)
           >> ":"
           >> *qi::char_;
    
        bool r = qi::parse(begin,
                           end,
                           duplicate,
                           output);
    
        std::cout << std::boolalpha
                  << r << " "
                  << (begin == end) << " '"
                  << output.first << "' \""
                  << output.second << "\""
                  << std::endl;
    
        return 0;
    }
    

    这个输出:

    true true '/' "/bar"
    

    【讨论】:

    • Hrrrrmmmm?如果你也想“发出”这个字符——这在解析的上下文中没有任何意义,对吧? &amp;! 解析器运算符都不使用任何输入。因此,显而易见的方法是“处理”您在以下表达式中测试的 character - 例如。 absolute_path/relative_path 在我的粗略示例中。对凤凰、当地人和其他人的需求为零。
    • 我不确定您所说的absolulte_path/relative_path 是什么意思。我确实想“捕获”(即“发射”?)/,然后继续解析,就好像我从未见过它一样。这就是你的例子吗?我的印象是它没有,但我没有测试过。
    • @3noch 当然,是什么阻止了后续解析器“捕获”/?我链接到操作员的文档:)
    • @sehe 我意识到您的示例允许第一个解析器测试 /,但我需要第一个解析器将/ 添加到它的属性(即“捕获”它),然后将它“放回”到流中,以便下一个解析器从/ 开始继续运行。
    • 我承认“发射”这个词不是官方术语,但根据我的经验,很少有人熟悉合成和继承属性的术语。我的意思是要综合属性需要完成以下工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    相关资源
    最近更新 更多