【问题标题】:Boost spirit how check value of token?Boost Spirit如何检查代币的价值?
【发布时间】:2016-06-27 20:49:36
【问题描述】:

如何在下一个代码中检查最后一个 tok.identifier 的值是“=”字符?

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

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

【问题讨论】:

  • identifier= 在哪个宇宙中匹配?此外,如果您需要帮助,请包括令牌定义(在您的 SSCCE 中)。您使用的是actor_lexer 吗?你在用token_def<T>吗?您是否在词法分析器声明中将Ts 添加到mpl::vector
  • 我使用token_def<T>,并且我使用带有解析器lex::tokenize_and_parse的词法分析器。询问中的代码来自解析器/语法。
  • 我知道它来自规则定义。但是您没有显示任何相关类型。抱歉,但这意味着我们无能为力(除了自己编写整个代码,而且 (a) 我有更好的时间来处理 (b) 只会冒着用不相关代码回答的风险)

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


【解决方案1】:

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))
                    );

【讨论】:

  • 我刚刚检查了 boost 1.65.1。 qi::lit 是为 char、string、bool、整数和实数定义的。它没有为 lex::token_def 定义。
  • 我从来没有说过它叫lit。它不是。我认为是id_token(id)token_id(id) 或其他东西(甚至可能是any_token(id) 或只是qi::token(id))。我稍后再找
  • 好的。我检查了词法分析器中定义的所有终端。我找到了这些:in_state、plain_raw_token、plain_token、plain_token_range、plain_tokenid、plain_tokenid_range、plain_tokenid_mask、state_switcher 和 state_switcher_context。他们都不检查令牌的文字值。
  • 您是否碰巧有一个使用您的代码的独立示例?我明天会试着看看这个。
  • 我没有。我在我的项目中有它并且它正在工作。我不能分享这个项目。只需复制并粘贴我发布的内容并尝试使用类似于r = qi::lit(tok.identifier, ''match-this-literally") 的规则。就我而言,它在解析点语言 (graphviz.org/content/dot-language) 时很有用。检查 compass_pt 规则。它有这些 n, ne, e, se...,它们不是关键字。不在词法分析器中为它们定义专用实体会更容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 2013-02-12
  • 1970-01-01
相关资源
最近更新 更多