0

私の問題は次のとおりです。次のように定義されたastノードがあります。

struct foo_node{
    std::vector<std::string> value;
}

そして、構造体に解析するためのこのようなパーサーがあります。これは正常に機能します。

typedef x3::rule<struct foo_node_class, foo_node> foo_node_type;
const foo_node_type foo_node = "foo_node";
auto const foo_node_def = "(" >> +x3::string("bar") >> ")";

ここで、パーサーが括弧なしで も解析することを達成したいと考えてい"bar"ますが、それが単一のバーである場合に限ります。私はこのようにそれをやろうとしました:

    auto const foo_node_def = x3::string("bar") 
                             | "(" > +x3::string("bar") > ")";

しかし、これはコンパイル時エラーを引き起こしx3::string("bar")ますstd::vector<std::string>。私の質問は、x3::string("bar")パーサー (および文字列を返す他のすべてのパーサー) がベクトルに解析することをどのように達成できますか?

4

1 に答える 1

2

単一の要素を解析し、単一要素のコンテナー属性として公開する方法は次のx3::repeat(1) [ p ]とおりです。

Live On Coliru

#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>

namespace x3 = boost::spirit::x3;

struct foo_node {
    std::vector<std::string> value;
};

BOOST_FUSION_ADAPT_STRUCT(foo_node, value)

namespace rules {
    auto const bar 
        = x3::string("bar");

    auto const foo_node
        = '(' >> +bar >> ')'
        | x3::repeat(1) [ +bar ]
        ;
}

int main() {
    for (std::string const input : {
            "bar",
            "(bar)",
            "(barbar)",
            })
    {
        auto f = input.begin(), l = input.end();

        foo_node data;
        bool ok = x3::parse(f, l, rules::foo_node, data);

        if (ok) {
            std::cout << "Parse success: " << data.value.size() << " elements\n";
        } else {
            std::cout << "Parse failed\n";
        }

        if (f != l)
            std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}

版画

Parse success: 1 elements
Parse success: 1 elements
Parse success: 2 elements
于 2016-08-21T19:01:59.030 に答える