2016-03-12 3 views
0

Как я могу проверить следующий код, что значение последнего tok.identifier is '=' - символ?Повысить дух, как проверить значение токена?

parameter = (
        tok.identifier 
        >> ((lit(":") 
        >> tok.identifier) | 
        (tok.identifier >> statement)) 
        ); 

EDIT. Я объявляю идентификатор lex::token_def<std::string> identifier;

+0

в том, что вселенная делает '' identifier' матч = '?. Кроме того, если вы хотите получить помощь, укажите определения токенов (в вашем SSCCE). Вы используете 'actor_lexer'? Вы используете 'token_def '? Добавляете ли вы 'T' к 'mpl :: vector' в декларации lexer? – sehe

+0

Я использую 'token_def ' и, я использую lexer с парсером 'lex :: tokenize_and_parse'. Этот код запрашивается от парсера/грамматики. – Viola

+1

Я знаю, что это определение правила. Но вы не показываете какие-либо из соответствующих типов. Извините, но это означает, что мы не можем помочь (за исключением того, чтобы составить весь код самостоятельно, и (a) у меня есть лучшие вещи, связанные с моим временем (b), которые просто рискуют ответить на нерелевантный код) – sehe

ответ

0

Соответствующая концепция в boost::spirit::qi описана qi::lit. Вы должны создать qi::lit для своих жетонов. Вот пример:

template <typename TokenAttr> 
struct LiteralToken : qi::primitive_parser<LiteralToken<TokenAttr>> 
{ 
    LiteralToken(const lex::token_def<TokenAttr> &tok, const TokenAttr &value) 
     : id(tok.id()) 
     , value(value) 
    {} 

    template <typename Context, typename Iterator> 
    struct attribute 
    { 
     typedef unused_type type; 
    }; 

    template <typename Iterator, typename Context, typename Skipper, typename Attribute> 
    bool parse(Iterator& first, Iterator const& last, Context& context, Skipper const& skipper, Attribute& attr_) const 
    { 
     typedef typename Iterator::token_type::token_value_type token_value_type; 
     typedef typename Iterator::base_iterator_type base_iterator_type; 

     base_iterator_type it; 

     qi::skip_over(first, last, skipper); 
     if (first != last && id == first->id()) 
     { 
      auto v = boost::get<boost::iterator_range<base_iterator_type>>(first->value()); 
      if (v == value) 
      { 
       traits::assign_to(*first, attr_); 
       ++first; 
       return true; 
      } 
     } 
     return false; 
    } 

    typename lex::token_def<TokenAttr>::id_type id; 
    TokenAttr         value; 
}; 

namespace boost 
{ 
    namespace spirit 
    { 
     template <typename A0, typename A1> 
     struct use_terminal< 
      qi::domain 
      , terminal_ex<tag::lit, fusion::vector2<A0, A1>> 
      , typename enable_if<boost::is_same<A0, lex::token_def<std::string>>>::type 
      > : mpl::true_ 
     {}; 

     namespace qi 
     { 
      template <typename Modifiers, typename A0, typename A1> 
      struct make_primitive< 
       terminal_ex<tag::lit, fusion::vector2<A0, A1> > 
       , Modifiers 
       , typename enable_if<boost::is_same<A0, lex::token_def<std::string>>>::type 
       > 
      { 
       typedef LiteralToken<std::string> result_type; 

       template <typename Terminal> 
       result_type operator()(Terminal const& term, unused_type) const 
       { 
        return result_type(fusion::at_c<0>(term.args), fusion::at_c<1>(term.args)); 
       } 
      }; 
     } 
    } 
} 

Тогда вы можете написать

parameter = (
        lit(tok.identifier, "=") 
        >> ((lit(":") 
        >> tok.identifier) | 
        (tok.identifier >> statement)) 
        ); 
+0

Я очень помню это уже существует в библиотеке – sehe

+0

Я только что проверил boost 1.65.1. qi :: lit задается для char, string, bool, integers и real numbers. Он не определен для lex :: token_def. – noxmetus

+0

Я никогда не говорил, что это называется 'lit'. Это не. Я думаю, что это был 'id_token (id)' или 'token_id (id)' или что-то (возможно, даже 'any_token (id)' или просто 'qi :: token (id)'). Я буду искать его позже – sehe

Смежные вопросы