【问题标题】:How to rewrite qi parsers with inherited attributes in x3?如何在 x3 中重写具有继承属性的 qi 解析器?
【发布时间】:2017-03-31 20:14:56
【问题描述】:

如果继承的属性用于语义动作,我们可以使用x3::with 指令。

如果我们想将属性用作解析器的一部分怎么办?例如,一个简单的解析器匹配 1 个或多个字母字符,但该字符来自参数字符集。

qi::rule<std::string::const_iterator, qi::unused_type(char const*)> rule =
    +(qi::alpha - qi::char_(qi::_r1));

或者参数字符集可以用作惰性解析器。

qi::rule<std::string::const_iterator, qi::unused_type(char const*)> rule =
    +(qi::alpha - qi::lazy(qi::_r1));

x3::with 指令将此本地值放在上下文中。我不确定我们是否可以在语义操作之外使用此上下文并最终生成解析器。

【问题讨论】:

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


    【解决方案1】:

    只要放弃把一切都归于规则的旧习惯。

    #include <boost/spirit/home/x3.hpp>
    #include <iostream>
    
    namespace x3 = boost::spirit::x3;
    
    template <typename... Args>
    auto negate(Args&&... p) {
        return +(x3::char_ - x3::char_(std::forward<Args>(p)...));
    };
    
    int main() {
        std::string input("all the king's men and all the king's horses"), parsed;
        if (parse(input.begin(), input.end(), negate("horse"), parsed))
            std::cout << "'" << input << "' -> '" << parsed << "'\n";
    }
    

    Live On Coliru,打印:

    'all the king's men and all the king's horses' -&gt; 'all t'

    第二味:

    #include <boost/spirit/home/x3.hpp>
    #include <iostream>
    
    namespace x3 = boost::spirit::x3;
    
    template <typename Sub>
    auto negate(Sub p) {
        return +(x3::char_ - x3::as_parser(p));
    };
    
    int main() {
        std::string input("all the king's men and all the king's horses"), parsed;
        if (parse(input.begin(), input.end(), negate("horse"), parsed))
            std::cout << "'" << input << "' -> '" << parsed << "'\n";
    }
    

    Live On Coliru,打印:

    'all the king's men and all the king's horses' -&gt; 'all the king's men and all the king's '

    更复杂的东西

    您还可以在自定义解析器中聚合子解析器:

    如果您需要递归规则来传递,我建议x3::with&lt;&gt;(尽管我不确定上下文是否为with&lt;&gt; 建立可重入状态,除非您能找到,否则您需要测试精确的语义文档)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 2014-06-11
      • 1970-01-01
      • 2023-02-22
      • 1970-01-01
      相关资源
      最近更新 更多