Как использовать косую черту в шаблонах Spirit Lex?

Код ниже компилируется нормально с

clang ++ -std = c ++ 11 test.cpp -o test

Но при запуске выдается исключение

завершить вызов после броска экземпляра
‘Подталкивание :: лексер :: runtime_error’
what (): Lookahead (‘/’) пока не поддерживается.

Проблема — косая черта (/) во входных данных и / или регулярных выражениях (строки 12 и 39), но я не могу найти решение, как избежать этого правильно. Есть намеки?

#include <string>
#include <cstring>
#include <boost/spirit/include/lex.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

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

std::string regex("FOO/BAR");

template <typename Type>
struct Lexer : boost::spirit::lex::lexer<Type> {
Lexer() : foobar_(regex) {
this->self.add(foobar_);
}
boost::spirit::lex::token_def<std::string> foobar_;
};

template <typename Iterator, typename Def>
struct Grammar
: qi::grammar <Iterator, qi::in_state_skipper<Def> > {
template <typename Lexer> Grammar(const Lexer & _lexer);
typedef qi::in_state_skipper<Def> Skipper;
qi::rule<Iterator, Skipper> rule_;
};
template <typename Iterator, typename Def>
template <typename Lexer>
Grammar<Iterator, Def>::Grammar(const Lexer & _lexer)
: Grammar::base_type(rule_) {
rule_ = _lexer.foobar_;
}

int main() {
// INPUT
char const * first("FOO/BAR");
char const * last(first + strlen(first));

// LEXER
typedef lex::lexertl::token<const char *> Token;
typedef lex::lexertl::lexer<Token> Type;
Lexer<Type> l;

// GRAMMAR
typedef Lexer<Type>::iterator_type Iterator;
typedef Lexer<Type>::lexer_def Def;
Grammar<Iterator, Def> g(l);

// PARSE
bool ok = lex::tokenize_and_phrase_parse (
first
, last
, l
, g
, qi::in_state("WS")[l.self]
);

// CHECK
if (!ok || first != last) {
std::cout << "Failed parsing input file" << std::endl;
return 1;
}
return 0;
}

1

Решение

Как Sehe указывает на, / скорее всего, будет использоваться в качестве оператора, который, скорее всего, синтаксис flex. К сожалению, Дух не использовал больше обычный синтаксис (не то, чтобы я думал, что другой синтаксис более элегантен; он просто путается со всеми тонкими вариациями синтаксиса регулярных выражений).

Если вы посмотрите на re_tokeniser.hpp:

// Not an escape sequence and not inside a string, so
// check for meta characters.
switch (ch_)
{
...
case '/':
throw runtime_error("Lookahead ('/') is not supported yet.");
break;
...
}

Он думает, что вы не в escape-последовательности и не внутри строки, поэтому он проверяет метасимволы. / считается метасимволом для предпросмотра (даже если эта функция не реализована) и должна быть экранирована, несмотря на документы Boost, не говоря уже о том, что.

Попробуйте убежать от / (не во входных данных) с обратной косой чертой (т.е. "\\/", или же "\/" если используется необработанная строка). С другой стороны, другие предложили использовать [/].

Я бы посчитал это ошибкой в ​​документации Spirit Lex, поскольку в ней не указано, что / должен быть сбежал.


Редактировать: слава к sehe а также cv_and_he, кто помог исправить некоторые из моих предыдущих мыслей. Если они отправят ответ здесь, обязательно дайте им +1.

1

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector