【问题标题】:Boost Spirit grammar custom attributeBoost Spirit语法自定义属性
【发布时间】:2017-02-20 04:52:20
【问题描述】:

正在尝试学习 Boost::Spirit 并希望解决一个 c 样式标识符的简单示例。下面的语法无法编译声明“incompatible_start_rule”。这个语法的目标是返回一个字符串而不是字符串向量,就像默认的属性传播规则那样。

template <typename IT>
struct cppIdentifier : qi::grammar<IT, std::string, space_type()>
{

    cppIdentifier() : cppIdentifier::base_type(start)
    {
        start = char_("a-zA-Z_")[boost::phoenix::push_back(_val, _1)]
                >> *(char_("a-zA-Z0-9_")[boost::phoenix::push_back(_val, _1)]);
    }

    qi::rule<IT, std::string, space_type> start;
};

我必须做什么才能实现这一目标?

另外请注意,我很清楚对于这个特定问题可能有许多替代的、更方便的选择,但我在学术上对如何操作自定义语法的属性类型很感兴趣,所以请将这些留在cmets 而不是答案。

【问题讨论】:

    标签: boost boost-spirit-qi


    【解决方案1】:

    首先,您需要使用 function-signature-style 模板参数来指定规则的输出属性类型(以及继承的属性类型,如果有)。代替qi::grammar&lt;IT, std::string, space_type()&gt;,试试qi::grammar&lt;IT, std::string(), space_type&gt;

    其次,您实际上并不需要语义操作 - 但如果您打算使用短语解析器,则需要 lexeme[] 指令:

    template <typename IT>
    struct cppIdentifier : qi::grammar<IT, std::string(), qi::space_type>
    {
        cppIdentifier() : cppIdentifier::base_type(start)
        {
            start = qi::lexeme[char_("a-zA-Z_") >> *(char_("a-zA-Z0-9_"))];
        }
    
        qi::rule<IT, std::string(), qi::space_type> start;
    };
    

    最后,确保您将兼容的船长对象传递给phrase_parse:

    std::string s = "HELLO 123";
    
    cppIdentifier < std::string::const_iterator> id;
    
    std::string ident;
    
    qi::phrase_parse(s.cbegin(), s.cend(), id, qi::space_type(), ident);
    
    // without lexeme[], ident becomes "HELLO123", not "HELLO"
    

    【讨论】:

    • 欢迎您,boost-spiritStack Overflow 标签中的新贡献者。非常感谢您的帮助!
    • 非常感谢!我从网站上学到了很多东西,包括从你的回答中,所以如果我能提供一些小的帮助,我会尝试。我还发现我从写自己的答案中学到了很多东西。
    • 是的!这行得通,谢谢。显然,我需要更深入地研究规则和语法模板参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 2012-02-28
    相关资源
    最近更新 更多