<commit_before>#include "ioplugins/pwinput.h"
#include <iomanip>
#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
#include <boost/fusion/adapted/std_array.hpp>
#include <boost/fusion/include/std_pair.hpp>

// TODO: make sure atomfmt is handled right!

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
using namespace std;
using namespace Vipster;
using namespace qi;
using pwmap = std::map<std::string,std::string>;

namespace boost { namespace spirit { namespace traits {
    template <typename T, size_t N>
        struct is_container<std::array<T, N>, void> : mpl::false_ { };
} } }

BOOST_FUSION_ADAPT_STRUCT(
        IO::PWData,
        data,
        mol
)

BOOST_FUSION_ADAPT_STRUCT(
        PseEntry,
        m,
        PWPP
)

BOOST_FUSION_ADAPT_STRUCT(
        Atom,
        name,
        coord,
        fix
)

BOOST_FUSION_ADAPT_STRUCT(
        KPoints,
        active,
        mpg,
        discrete
)

BOOST_FUSION_ADAPT_STRUCT(
        KPoints::MPG,
        x,
        y,
        z,
        sx,
        sy,
        sz
)

BOOST_FUSION_ADAPT_STRUCT(
        KPoints::Discrete,
        properties,
        kpoints
)

BOOST_FUSION_ADAPT_STRUCT(
        DiscreteKPoint,
        pos,
        weight
)

template<typename Iterator>
struct pwi_parse_grammar
        : grammar<Iterator, IO::PWData(), blank_type>
{
    pwi_parse_grammar(): pwi_parse_grammar::base_type(file)
    {
        //TODO: ignore comments
        //TODO: change skipper to remove eols
        //TODO: honor CellFmt
        file = param > *eol > mol;

        /* Namelists:
         * &NAME
         * key=value, key=value
         * key=value
         * !comment
         * /
         */
        nl_names.add
              ("control", &IO::PWParam::control)
              ("system", &IO::PWParam::system)
              ("electrons", &IO::PWParam::electrons)
              ("ions", &IO::PWParam::ions)
              ("cell", &IO::PWParam::cell)
        ;
        param       = ('&' > no_case[nl_names[_a = _1]] > eol
                      > nl[phx::bind(
                        [](pwmap IO::PWParam::* v, IO::PWParam& p, pwmap m)
                        { p.*v = m; }, _a, _val, _1)]
                      > eol > '/') % *eol;
        nl          = nl_entry % (eol|',');
        nl_entry    = key > qi::lit('=') > value;
        value       = fstr | key;
        key         = +(qi::graph - qi::char_("=/,'"));
        fstr        = qi::char_('\'')
                      >> qi::lexeme[*(qi::char_ - '\'')]
                      > qi::char_('\'');

        /* Cards:
         * NAME {options}
         * #comment
         * !comment
         * <content><commit_msg>fix PWI-Namelist separators<commit_after>#include "ioplugins/pwinput.h"
#include <iomanip>
#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
#include <boost/fusion/adapted/std_array.hpp>
#include <boost/fusion/include/std_pair.hpp>

// TODO: make sure atomfmt is handled right!

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
using namespace std;
using namespace Vipster;
using namespace qi;
using pwmap = std::map<std::string,std::string>;

namespace boost { namespace spirit { namespace traits {
    template <typename T, size_t N>
        struct is_container<std::array<T, N>, void> : mpl::false_ { };
} } }

BOOST_FUSION_ADAPT_STRUCT(
        IO::PWData,
        data,
        mol
)

BOOST_FUSION_ADAPT_STRUCT(
        PseEntry,
        m,
        PWPP
)

BOOST_FUSION_ADAPT_STRUCT(
        Atom,
        name,
        coord,
        fix
)

BOOST_FUSION_ADAPT_STRUCT(
        KPoints,
        active,
        mpg,
        discrete
)

BOOST_FUSION_ADAPT_STRUCT(
        KPoints::MPG,
        x,
        y,
        z,
        sx,
        sy,
        sz
)

BOOST_FUSION_ADAPT_STRUCT(
        KPoints::Discrete,
        properties,
        kpoints
)

BOOST_FUSION_ADAPT_STRUCT(
        DiscreteKPoint,
        pos,
        weight
)

template<typename Iterator>
struct pwi_parse_grammar
        : grammar<Iterator, IO::PWData(), blank_type>
{
    pwi_parse_grammar(): pwi_parse_grammar::base_type(file)
    {
        //TODO: ignore comments
        //TODO: change skipper to remove eols
        //TODO: honor CellFmt
        file = param > *eol > mol;

        /* Namelists:
         * &NAME
         * key=value, key=value
         * key=value
         * !comment
         * /
         */
        nl_names.add
              ("control", &IO::PWParam::control)
              ("system", &IO::PWParam::system)
              ("electrons", &IO::PWParam::electrons)
              ("ions", &IO::PWParam::ions)
              ("cell", &IO::PWParam::cell)
        ;
        param       = ('&' > no_case[nl_names[_a = _1]] > eol
                      > nl[phx::bind(
                        [](pwmap IO::PWParam::* v, IO::PWParam& p, pwmap m)
                        { p.*v = m; }, _a, _val, _1)]
                      > eol > '/') % *eol;
        nl          = nl_entry % eol;
        nl_entry    = key > qi::lit('=') > value >> -lit(',');
        value       = fstr | key;
        key         = +(qi::graph - qi::char_("=/,'"));
        fstr        = qi::char_('\'')
                      >> qi::lexeme[*(qi::char_ - '\'')]
                      > qi::char_('\'');

        /* Cards:
         * NAME {options}
         * #comment
         * !comment
         * <content>
{'fraction_non_alphanumeric': 0.1362763915547025, 'fraction_numerical': 0.0010469377072064212, 'mean_word_length': 1.8674337168584292, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1860993', 'n_tokens_mistral': 2021, 'n_tokens_neox': 1957, 'n_words': 360}