提升精神如何检查令牌的价值?

时间:2016-03-12 16:07:50

标签: c++ parsing boost boost-spirit boost-spirit-lex

我如何在下一个代码中检查上一个tok.identifier的值是'=' - 字符?

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

EDIT。我声明了标识符lex::token_def<std::string> identifier;

1 个答案:

答案 0 :(得分: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))
                    );