2015-07-14 5 views
1

код ниже компилирует штрафа сКак использовать косую черту в стиле Spirit Lex?

лязгом ++ -std = C++ 11 test.cpp -o тест

Но при запуске исключение

Terminate называется после броска экземпляр 'boost :: lexer :: 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; 
} 
+0

Я бы сказал, упростите это, чтобы он работал без '/' (т. Е. Просто прочитал и проанализировал 'FOOBAR'). Затем, как только вы начнете работать, попробуйте добавить '/' обратно. – Cornstalks

ответ

1

Как sehe points out, /, скорее всего, предназначен для использования в качестве оператора опережения, вероятно, принимая после the syntax of flex. К сожалению, Spirit не будет использовать больше normal lookahead syntax (не то, что я думаю, что другой синтаксис более изящный, он просто запутывает все тонкие вариации в синтаксисе regex).

Если вы посмотрите на 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; 
    ... 
} 

Он думает, что вы не в управляющей последовательности, ни ты внутри строки, так что это проверка на мета-символов. / считается метасимволом для просмотра (хотя функция не реализована) и должна быть экранирована, despite the Boost docs not mentioning that at all.

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

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


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

+0

Я пытался избежать косой черты с помощью «\\ /», «\ /» и «[\]». Никакое решение не разработано. – user1587451

+0

Однако сбой с другой ошибкой. (В частности: 'Assertion failed: (std :: size_t (~ 0)! = State), function set_lexer_state, file /usr/local/include/boost/spirit/home/lex/qi/state_switcher.hpp, строка 87.'). Я не очень хорошо знаю Spirit, но похоже, что у вас есть еще одна проблема в вашем lexer/parser. Этот ответ должен быть правильным для решения проблемы слэш. Для другого вопроса ... Я не уверен, что сказать. – Cornstalks

+0

Это не упорядоченный выбор. Также, имея в виду нотацию спецификации PEG, это красная селедка, потому что здесь мы не указываем грамматику. Мы указываем шаблоны токенов. Они используют подмножество регулярных выражений: http://www.boost.org/doc/libs/1_58_0/libs/spirit/doc/html/spirit/lex/quick_reference/lexer.html (и, кстати, это то, что ошибка сообщение) – sehe