【问题标题】:Boost spirit semantic action提升精神语义动作
【发布时间】:2016-06-30 07:44:07
【问题描述】:

我正在尝试使用 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;
}

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

【问题讨论】:

  • 什么是无限错误?为什么不发布相关部分/完整?另外,我闻到了XY problem,我看不到任何需要语义操作的地方。
  • 一个很长(就行而言)的错误很难在 stackoverflow 上发布。我只想将例程与 enum_specifier 检测相关联。我对谷歌进行了一些研究,但我没有发现任何与我的情况相同的东西。我试图在这里调用语义动作:[boost::phoenix::bind(dummy)]
  • 不在此处,“test.cpp|4 col 22| 致命错误:spirit.hpp:没有这样的文件或目录”
  • @sehe 是的,可能我很困惑。我的最终目标是创建一个语言翻译器。源语言包含枚举和类。所以我想开始创建一个解析器,它可以识别枚举结构和他的名字/元素并打印出不同的东西。示例: INPUT: enum pippo { pluto=0, dog}; --> 输出:枚举 pippo { PIPPO_pluto=0, PIPPO_dog=1};因为,在第二步中,解析器将变得更加复杂。我想为每种对象提供一对不同的解析器/输出函数。如何修改您的代码以移出输出功能?
  • 这让我哭了:using namespace std; using namespace boost::spirit; using boost::phoenix::bind;

标签: c++ boost boost-spirit


【解决方案1】:

我不确定如何理解这个例子。你结合了 Spirit "Classical" v1(已经过时了十多年)、Karma 标头(即 Spirit V2 并且 与解析无关)和 Utree 的一些内容(仅 V2 并且已弃用。

然后还有 Boost Lambda 和 Boost Phoenix,是否很好?哦。 Aaaaand 厨房水槽 Boost Bind。

然后你使用混合所有命名空间

using namespace std;
using namespace boost::spirit;

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

让我给你看样例,看看我能不能拿出一个固定的版本。


10 分钟车程:


灵气演示

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

这是利用 Qi 的版本

  1. 自动属性传播 (Boost Spirit: "Semantic actions are evil"?)

  2. 船长 (Boost spirit skipper issues)

  3. List operator (%)

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

【讨论】:

    猜你喜欢
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    相关资源
    最近更新 更多