在语义动作中删除精神气象征

时间:2013-07-10 12:14:27

标签: c++ boost-spirit boost-spirit-qi

在其他线程中,我已经阅读了如何在语义操作中向符号表添加符号,但我不知道如何删除它。

我的问题背后的想法是,我想允许在解析的文本中重命名关键字。因此,给出了几个带值的关键字,但用户可以重新分配它们:

reassign(keyword)(mykeyword)

我有一个带语义动作的规则

using namespace boost::spirit::qi;
...
qi::symbols<char, TYPE> keywords;
...
key_replace = ( lit("reassign") >> lit("(") >> keywords >> lit(")") >> 
                                   lit("(") >> lexeme [ raw [ ( alpha >> *( alnum | '_' ) ) ] ] >> lit (")") ) 
              [ boost::phoenix::bind(keywords.remove, _1) ]; // TODO: replace not remove

问题是,我没有获得对符号本身的引用,而是引用了存储的值。因此调用remove不起作用。

如何在解析过程中获得对已解析符号的引用?

在解析过程中保留值时是否有更简单的方法来交换符号?

1 个答案:

答案 0 :(得分:3)

天真的'凤凰'方式将是

 rule_assign = key >> value
        [ phx::bind(keywords.add, _1, _2) ];
 rule_remove = key
        [ phx::bind(keywords.remove, _1) ];

 // and voila: (BROKEN)
 rule_replace = key >> value
        [ phx::bind(keywords.remove, _1),
          phx::bind(keywords.add, _1, _2)
        ];

后者不起作用,我相信由于第一个绑定返回一个重载operator,本身的对象,它优先于phoenix的{​​{1}}。

我建议你写一个小帮手来解决这个问题:

operator,

这透明地分配或重新分配struct assign_symbol_f { assign_symbol_f(Symbols& sym) : sym(sym) {} typedef bool result_type; template<typename Key, typename Value> bool operator()(Key const& key, Value const& value) const { bool replaced = (nullptr != sym.find(key)); sym.remove(key); sym.add(key, value); return replaced; } private: Symbols& sym; }; 树中的项目。使用方法如下:

symbols

现在,你可以拆分并更具体:

rule_replace_or_add = key >> value
        [ phx::bind(assign_symbol_f(keywords), qi::_1, qi::_2) ];

加成

作为奖励,您可以通过为您的仿函数创建一个懒惰的演员来获得一些语法糖

assign_symbol_f assign_sym(keywords);

rule_assign = key >> value
        [ qi::_pass = !phx::bind(assign_sym, _1, _2) ];

rule_replace = key >> value
        [ qi::_pass =  phx::bind(assign_sym, _1, _2) ];

看吧!不再phx::function<assign_symbol_f> assign_sym; // use it like rule_assign = key >> value [ qi::_pass = assign_sym(_1, _2) ]; rule_replace = key >> value [ qi::_pass = assign_sym(_1, _2) ];

完整演示

完成一个基本的测试套件:)

phx::bind