повышение духа ожидания ожидания - PullRequest
0 голосов
/ 17 февраля 2011

Я хочу разобрать вектор следующей структуры:

BOOST_FUSION_ADAPT_STRUCT(
    event_model::OTNDescriptor,
    (int32_t, qualifier)
    (int32_t, ordinal)
    (std::string, name)
    (int32_t, type)
)

Моя грамматика выглядит следующим образом:

struct swat_types_ : qi::symbols<char, unsigned>
{
    swat_types_()
    {
        using namespace event_model;

        add
            ("int", SWAT_INT4)
            ("int4", SWAT_INT4)
            ("int8", SWAT_INT8)
            ("bigint", SWAT_INT8)
            ("string", SWAT_STRING)
        ;
    } 
} swat_types;

template<typename Iterator>
struct Rules
{
    qi::rule<Iterator, event_model::OTNDescriptor(), ascii::space_type>
        data_member_line;
    qi::rule<Iterator, std::string()> data_name;
    qi::rule<Iterator, void(int&, std::string&)> data_identifier_pair;
    qi::rule<   Iterator,
                std::vector< event_model::OTNDescriptor>(),
                ascii::space_type> dm_lines;

    Rules() {
        data_name =
            + (char_("a","z") | char_("A","Z") | char_('_'));

        data_identifier_pair =
            lexeme[int_ [ _r1 = _1] > ':' > data_name [ _r2 = _1]];

        data_member_line =
            eps [ at_c<0>(_val) = event_model::OTN_REQUIRED ]
            >>  -( no_case[lit("optional")]
                        [at_c<0>(_val) = event_model::OTN_OPTIONAL]
                |   no_case[lit("required")]
                        [at_c<0>(_val) = event_model::OTN_REQUIRED])
            > data_identifier_pair( at_c<1>(_val), at_c<2>(_val) )
            > no_case[swat_types [at_c<3>(_val) = _1]]

            > ';'
        ;
        //dm_lines = data_member_line >> data_member_line;
        dm_lines = data_member_line >> *(data_member_line);
    }
};

Мой Харнас выглядит так:

std::string str4("REquireD 0:lala int4; REquireD 1:googoo int4; ");

std::string::const_iterator iter4=str4.begin();
std::string::const_iterator end4=str4.end();

std::vector<event_model::OTNDescriptor> res4;

r = phrase_parse(iter4, end4, rules.dm_lines, boost::spirit::ascii::space, res4);

for(std::vector<event_model::OTNDescriptor>::iterator it = res4.begin(); it < ires4.end(); it++)
{
    std::cout << it->name << "\n";
}

Если я переключу спецификацию правила с спецификации клини с звездой на совпадение последовательности без ошибок.

//dm_lines = data_member_line >> data_member_line;
dm_lines = data_member_line >> *(data_member_line);

в противном случае я получаю сообщение об ошибке при попытке разобрать мое примерное предложение (показано на харнасе).

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::spirit::qi::expectation_failure<__gnu_cxx::__normal_iterator<char const*, std::string> > > >'
  what():  boost::spirit::qi::expectation_failure
Aborted

В идеале я хочу написать правило, подобное этому dm_lines = +(data_member_line) (это тоже не работает). Что происходит, что вызывает ошибку ожидания при использовании операторов «*» и «+»? но НЕ при сопоставлении последовательности? И как мне это исправить.

1 Ответ

3 голосов
/ 17 февраля 2011

Причина ожидаемого сбоя заключается в том, что как только вы начнете использовать plus или Kleene, встроенный синтаксический анализатор (data_member_line) будет вызываться более одного раза. Его последний вызов, естественно, потерпит неудачу, так как больше нет доступных входных данных. В вашем случае это событие будет «распознано» только первой точкой ожидания, поскольку все компоненты до этого являются необязательными (они никогда не завершаются).

...