【问题标题】:Boost spirit: Parse char_ with changing local variable value提升精神:通过改变局部变量值解析 char_
【发布时间】:2017-02-17 15:19:57
【问题描述】:

我想实现一个需要解析实例名称和路径的语法,其中路径是由分隔符分隔的实例名称列表。分隔符可以是.(句点)或/(斜杠)在列出路径之前在输入文件中给出,例如:

DIVIDER .
a.b.c
x.y.z

一旦设置,整个文件的分隔符永远不会改变(即,如果设置为.,遇到像a/b/c 这样的路径不应正确解析)。由于我事先不知道分隔符是什么,所以我正在考虑将其存储在我的语法变量中,并在相应的char_ 解析器中使用该值(当然,实际的语法要复杂得多,但这是我遇到麻烦的部分)。

这有点类似于这个问题:Boost spirit using local variables 但不是我想要的,因为使用 Nabialek 技巧允许在设置分隔符后解析“无效”路径。

我不是在这里要求一个完整的解决方案,但我的问题本质上是这样的:我可以将值解析为我的语法成员,然后使用这些值来进一步解析剩余的输入吗?

【问题讨论】:

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


    【解决方案1】:

    我会使用继承属性:

    qi::rule<It, std::string(char)> element = *~qi::char_(qi::_r1);
    qi::rule<It, std::vector<std::string>(char)> path = element(qi::_r1) % qi::char_(qi::_r1);
    
    // use it like:
    std::vector<std::string> data;
    bool ok = qi::parse(f, l, path('/'), data);
    

    或者你/可以/确实绑定到一个局部变量:

    char delim = '/';
    qi::rule<It, std::string()> element = *~qi::char_(delim);
    qi::rule<It, std::vector<std::string>()> path = element % qi::char_(delim);
    
    // use it like:
    std::vector<std::string> data;
    bool ok = qi::parse(f, l, path, data);
    

    如果您需要它是动态的,请使用boost::phoenix::ref:

    char delim = '/';
    qi::rule<It, std::string()> element = *~qi::char_(boost::phoenix::ref(delim));
    qi::rule<It, std::vector<std::string>()> path = element % qi::char_(boost::phoenix::ref(delim));
    
    // use it like:
    std::vector<std::string> data;
    bool ok = qi::parse(f, l, path, data);
    

    【讨论】:

    • 谢谢,我的第一种方法几乎看起来像这样,但我遇到了无限循环。至少我现在知道这是可能的。将在星期一尝试并报告。
    • 是的,效果很好。非常感谢!编辑:使用具有继承属性的第一个变体。对我来说,这似乎是最干净易读的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多