Редактировать: Я вырвал лексер, так как он не интегрируется с Qi и просто сфабрирует грамматики (см. here).повысить дух lex и qi. Интеграция анализатора пропусков
Я пытаюсь вырастить грамматику на вершине рамки lex. Когда я пытаюсь переместить анализатор пропусков в грамматику, я начинаю получать ошибки.
Итак, сменив qi::grammar<>
и qi::rule<> event
подписи от <Iterator>
до <Iterator,void(),ascii::space_type>
. В структуре грамматики. Что мне нужно сделать?
Кроме того, я установил token_def
, чтобы опустить его атрибут для токена optional
и некоторых других. Почему он по-прежнему предоставляет мне действительный _val
в семантическом действии для необязательного в lexer? Причина, о которой я прошу, состоит в том, что я думал, что проблема связана со строковым атрибутом необязательного токена на rhs правила события в qi, не объединяющемся с сигнатурой атрибута 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;
};
Однако, 'lex :: pass_flags :: pass_ignore' отлично документирован, соответствует купюре. Дело в том, что вам не нужен традиционный шкипер. – sehe
Да, честно говоря, этот способ делать вещи делает грамматику еще чище, чем раньше. Если бы я использовал 'pass_ignore', я бы предположил, что мне даже не пришлось бы перескакивать через' qi :: in_state_skipper <> 'обручи в моей грамматике, и лексер молча пропустил бы токены WS? –
Всегда полезно искать [огромное количество отличных (и грустно убранных) спиритических ответов, сделанных sehe] (http://stackoverflow.com/search?q=user:85371+ [boost-spirit]) на этот сайт. [Этот, в частности] (http://stackoverflow.com/search?q=user%3A85371+ [boost-spirit] + lex + skipper) представляется подходящим. – llonesmiz