Fwd: Attribute collapsing error

Seth <[email protected]> Thu, 25 Oct 2018 00:54:27 +0200
Newsgroups gmane.comp.parsers.spirit.general
Message-ID <[email protected]>
On 18-10-18 15:11, Kamil Witecki wrote:
> Hello,
> I have encountered strange issues with X3 attribute rules. When
> working with alternative with unused_type and attribute Spirit cannot
> push attribute to optional.
>
> I am using Boost 1.65.1 (with clang) and 1.68.0 (with MSVC Express
> 2017 15.8.4) and its Spirit.X3 implementation.
>
> Is it an error in Spirit.X3 or I have misunderstood compound attribute
> rules? How to fix the grammar if the latter is true?
>
> Attached is minimal example reproducing the case, error log of MSVC
> and error log of clang. Uncommenting the noop semantic actions makes
> the example compile.
>
> Pozdrawiam,
> Kamil Witecki.


I'm not sure what /should/ automatically happen. This is what I'd write:
http://coliru.stacked-crooked.com/a/5b08cce708e6b60a

#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/optional/optional_io.hpp>
#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <iomanip> // std::quoted
using Node = std::pair<std::string, int>;


namespace x3 = boost::spirit::x3;

namespace bug {
    using namespace x3;

    auto node_  = x3::rule<class node_, Node>{ "node"
}                       = lexeme[+x3::graph] >> x3::int_;
    auto either = x3::rule<class either_, boost::optional<Node> >{
"either" } = node_ | 'a';

    static inline std::ostream& operator<<(std::ostream& os, Node const&
n) {
        return os << std::quoted(n.first) << " " << n.second;
    }
}

int main() {
    for (std::string const data: {"a 123", "a", "", "a trailing", "b 123
trailing"}) {
        std::cout << "\nInput: " << std::quoted(data) << "\n";

        boost::optional<Node> res;
        auto f = std::begin(data), l = std::end(data);

        if (phrase_parse(f, l, bug::either, x3::space, res)) {
            std::cout << "Parsed: ";
            if (res)
                std::cout << std::quoted(res->first) << " " <<
res->second << "\n";
            else
                std::cout << "(none)\n";
        } else {
            std::cout << "Parse failed\n";
        }

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

Which prints

Input: "a 123"
Parsed: "a" 123

Input: "a"
Parsed: (none)

Input: ""
Parse failed

Input: "a trailing"
Parsed: (none)
Remaining: "trailing"

Input: "b 123 trailing"
Parsed: "b" 123
Remaining: "trailing"

_______________________________________________
Spirit-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spirit-general