повысить дух lex и ци. Интеграция пропускающего парсера

редактировать : Я вырвал лексер, так как он не интегрируется с Ци и просто запутывает грамматику (см. Вот).


Я пытаюсь вырастить грамматику поверх основы духа lex. Когда я пытаюсь переместить анализатор пропуска в грамматику, я получаю ошибки.

Итак, меняя qi::grammar<> а также qi::rule<> event подписи от <Iterator> в <Iterator,void(),ascii::space_type>, В грамматической структуре. Что мне нужно сделать?

Дополнительно я установил token_def опустить его атрибут для optional токен и некоторые другие. Почему он до сих пор предоставляет мне действительный _val в семантическом действии для необязательного в лексере? Причина, по которой я спрашиваю, заключается в том, что я думал, что проблема связана с атрибутом строки необязательного токена в правой части правила события в ци, не объединяющейся с void() Атрибут подписи правила.

#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include<exception>

namespace lex = boost::spirit::lex;
namespace px = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Lexer>
struct tokens : lex::lexer<Lexer>
{
tokens()
: left_paranthesis("\"{\""),
right_paranthesis("\"}\""),
colon(":"),
namespace_("(?i:namespace)"),
event("(?i:event)"),
optional("(?i:optional)"),
required("(?i:required)"),
ordinal("\\d+"),
identifier("\\w+")

{
using boost::spirit::lex::_val;

this->self
= " "| left_paranthesis    [ std::cout << px::val("lpar") << std::endl]
| right_paranthesis   [ std::cout << px::val("rpar") << std::endl]
| colon               [ std::cout << px::val("colon") << std::endl]
| namespace_          [ std::cout << px::val("kw namesapce") << std::endl]
| event               [ std::cout << px::val("kw event") << std::endl]
| optional            [ std::cout << px::val("optional ")  << "-->" << _val << "<--" << std::endl]
| required            [ std::cout << px::val("required") << std::endl]
| ordinal             [ std::cout << px::val("val ordinal (") << _val << ")" << std::endl]
| identifier          [std::cout << px::val("val identifier(") << _val << ")" << std::endl];
}

lex::token_def<> left_paranthesis, right_paranthesis, colon;
lex::token_def<lex::omit> namespace_, event, optional, required;
lex::token_def<boost::uint32_t> ordinal;
lex::token_def<> identifier;
};

template <typename Iterator>
struct grammar : qi::grammar<Iterator>
{
template <typename TokenDef>
grammar(TokenDef const& tok)
: grammar::base_type(event)
{
//start = event;
event = tok.optional [ std::cout << px::val("== OPTIONAL") << std::endl];
}

qi::rule<Iterator> start;
qi::rule<Iterator> event;
};

// std::string test = "namespace{ event { OPtiONAL 124:hello_world RequireD} } ";

std::string test = "OPTIONAL";

int main()
{
typedef lex::lexertl::token<std::string::iterator, boost::mpl::vector<boost::uint32_t, std::string> > token_type;
typedef lex::lexertl::actor_lexer<token_type> lexer_type;
typedef tokens<lexer_type>::iterator_type iterator_type;

tokens<lexer_type> token_lexer;
grammar<iterator_type> grammar(token_lexer);

std::string::iterator first = test.begin();
std::string::iterator last = test.end();
bool r;

r = lex::tokenize_and_parse(first, last, token_lexer, grammar);

if(r)
;
else
{
std::cout << "parsing failed" << std::endl;
}
/*
lexer_type::iterator_type iter;

try
{
iter = token_lexer.begin(first,last);
}
catch(std::exception & e)
{
std::cout << e.what() << std::endl;
}

lexer_type::iterator_type end = token_lexer.end();

while (iter != end && token_is_valid(*iter))
++iter;
*/
}

Эта грамматика не работает:

template <typename Iterator>
struct grammar : qi::grammar<Iterator,void(),ascii::space_type>
{
template <typename TokenDef>
grammar(TokenDef const& tok)
: grammar::base_type(event)
{
//start = event;
event = tok.optional [ std::cout << px::val("== OPTIONAL") << std::endl];
}

qi::rule<Iterator> start;
qi::rule<Iterator,void(),ascii::space_type> event;
};

2

Решение

Как с большей частью духа. Если вы хотите сделать что-то РЕАЛЬНОЕ, вам придется часами искать решение, которое не документировано, а скрыто в примерах и списках рассылки. Серьезно рассматривая возможность перехода на ragel или flex / bison. Проблема не в том, что машина недоступна, а в том, что она не имеет документов.

В этом случае, просматривая документацию lex, можно получить обманчивое представление о вызовах API-интерфейса lex parser, который имеет tokenize_and_phrase_parse функция. Что на самом деле не работает, когда вы пытаетесь использовать его как qi::phrase_parse в документации также не объясняется, как подключить шкипера с помощью этой функции.

Подготовка к вводу космического шкипера в парсер выполняется путем изменения лексера, а затем с использованием некоторой недокументированной конструкции qi-Skipper, инициализирующей грамматику и правила. Вы можете увидеть это в действии в каталоге примеров lex (пример 5). Код, который компилируется и работает:

#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include<exception>

namespace lex = boost::spirit::lex;
namespace px = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;

template <typename Lexer>
struct tokens : lex::lexer<Lexer>
{
tokens()
: left_paranthesis("\"{\""),
right_paranthesis("\"}\""),
colon(":"),
namespace_("(?i:namespace)"),
event("(?i:event)"),
optional("(?i:optional)"),
required("(?i:required)"),
ordinal("\\d+"),
identifier("\\w+")

{
using boost::spirit::lex::_val;

this->self
=
left_paranthesis    [ std::cout << px::val("lpar") << std::endl]
| right_paranthesis   [ std::cout << px::val("rpar") << std::endl]
| colon               [ std::cout << px::val("colon") << std::endl]
| namespace_          [ std::cout << px::val("kw namesapce") << std::endl]
| event               [ std::cout << px::val("kw event") << std::endl]
| optional            [ std::cout << px::val("optional ")  << "-->" << _val << "<--" << std::endl]
| required            [ std::cout << px::val("required") << std::endl]
| ordinal             [ std::cout << px::val("val ordinal (") << _val << ")" << std::endl]
| identifier          [std::cout << px::val("val identifier(") << _val << ")" << std::endl];this->self("WS") =   lex::token_def<>("[ \\t\\n]+");
}lex::token_def<> left_paranthesis, right_paranthesis, colon;
lex::token_def<lex::omit> namespace_, event, optional, required;
lex::token_def<boost::uint32_t> ordinal;
lex::token_def<> identifier;
};

template <typename Iterator, typename Lexer>
struct grammar : qi::grammar<Iterator,qi::in_state_skipper<Lexer> >
{
template <typename TokenDef>
grammar(TokenDef const& tok)
: grammar::base_type(event)
{
//start = event;
event = tok.optional [ std::cout << px::val("== OPTIONAL") << std::endl];
}

qi::rule<Iterator> start;
qi::rule<Iterator, qi::in_state_skipper<Lexer> > event;
};

// std::string test = "namespace{ event { OPtiONAL 124:hello_world RequireD} } ";

std::string test = " OPTIONAL ";

int main()
{
typedef lex::lexertl::token<std::string::iterator, boost::mpl::vector<boost::uint32_t, std::string> > token_type;
typedef lex::lexertl::actor_lexer<token_type> lexer_type;
typedef tokens<lexer_type>::iterator_type iterator_type;

tokens<lexer_type> token_lexer;
grammar<iterator_type,tokens<lexer_type>::lexer_def> grammar(token_lexer);

std::string::iterator it = test.begin();
iterator_type first = token_lexer.begin(it, test.end());
iterator_type last = token_lexer.end();

bool r;

r = qi::phrase_parse(first, last, grammar, qi::in_state("WS")[token_lexer.self]);

if(r)
;
else
{
std::cout << "parsing failed" << std::endl;
}
/*
lexer_type::iterator_type iter;

try
{
iter = token_lexer.begin(first,last);
}
catch(std::exception & e)
{
std::cout << e.what() << std::endl;
}

lexer_type::iterator_type end = token_lexer.end();

while (iter != end && token_is_valid(*iter))
++iter;
*/
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]