提升精神语义行为

时间:2016-06-30 07:44:07

标签: c++ boost boost-spirit

我试图使用提升精神将简单的语义动作附加到我的语法中。

这是我的代码:

#define  BOOST_SPIRIT_NO_REGEX_LIB

#include "regex.h"
#include "spirit.hpp"
#include "spirit/actor/assign_actor.hpp"
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <string>


using namespace std;
using namespace boost::spirit;
using boost::phoenix::bind;



    // A plain function
    void dummy( )
    {
    int i=20;
        std::cout << i << std::endl;
    }





struct my_enum : public grammar<my_enum>
    {

    template <typename ScannerT>
      struct definition
        {
        definition(my_enum const& self)
          { 

          enum_specifier = enum_p >> '{' >> enum_list >> '}' [boost::phoenix::bind(dummy)];
          enum_p = str_p("enum");
          enum_list = +id_p >> *(',' >> +id_p);
          id_p = range_p('a','z');
          }

          rule<ScannerT> enum_specifier, enum_p, enum_list, id_p;
          rule<ScannerT> const& start() const { return enum_specifier; }
        };
    };

string input = "enum { ah, bk, ss  }";

int main ()
  {     
  my_enum e;
  int status = parse(input.c_str(), e, space_p).hit;
  cout << status << endl;
  return 0;
}

我得到一个我无法理解的无限错误。 COuld有人可以给我一些关于如何映射语义功能的建议/示例吗?

1 个答案:

答案 0 :(得分:3)

我不知道该怎么做这个例子。你结合了Spirit“Classical”v1(已经过时十多年了),Karma标题(这是Spirit V2 与解析无关),然后是一些Utree(仅限V2的和已弃用。

然后提升Lambda和Boost Phoenix,这是好的方法吗?哦。 Aaaaand <罢工>厨房水槽 Boost Bind。

然后使用

混合所有名称空间
using namespace std;
using namespace boost::spirit;

我不确定你期望发生什么。

让我看看你的样本,看看我是否能想出一个固定的版本。

10分钟后:

Spirit Qi Demo

我假设您真的想要解析这些值,并且您将使用语义操作来存储它们(例如,在矢量中)。

这是利用

的Qi版本
  1. 自动属性传播(Boost Spirit: "Semantic actions are evil"?

  2. 船长(Boost spirit skipper issues

  3. List operator (%)

  4. <强> Live On Coliru

    #include <boost/spirit/include/qi.hpp>
    
    namespace qi = boost::spirit::qi;
    
    template<typename Iterator, typename Skipper = qi::space_type>
    struct my_enum : public qi::grammar<Iterator, std::vector<std::string>(), Skipper> {
    
        my_enum() : my_enum::base_type(enum_specifier)
        {
            id_p           = +qi::alpha;
            enum_specifier = qi::lit("enum") >> '{' >> (id_p % ',') >> '}';
        }
    
      private:
        qi::rule<Iterator, std::vector<std::string>(), Skipper> enum_specifier;
        // lexeme (no skipper):
        qi::rule<Iterator, std::string()> id_p;
    };
    
    int main() {
        typedef std::string::const_iterator Iterator;
    
        std::string const input = "enum { ah, bk, ss  }";
        my_enum<Iterator> parser;
    
        std::vector<std::string> parsed;
    
        Iterator iter = input.begin(), end = input.end();
        bool ok = qi::phrase_parse(iter, end, parser, qi::space, parsed);
        if (ok) {
            std::cout << "Parse succes\n";
            for (auto& value : parsed)
            {
                std::cout << " -- " << value << "\n";
            }
        } else {
            std::cout << "Parse succes\n";
        }
    
        if (iter != end) {
            std::cout << "Remaining unparsed input: '" << std::string(iter, end) << "'\n";
        }
    
        return ok? 0 : 1;
    }
    

    打印

    Parse succes
     -- ah
     -- bk
     -- ss