c++ - boost spirit x3 变体和 std::pair

标签 c++ boost-spirit

我尝试运行一些简单的解析器来解析 [1, 11, 3, 6-4]。基本上,带有范围符号的整数列表。

我想在没有语义操作的情况下将所有内容都放入 AST 中。所以我使用 x3::variant。我的代码“看起来”与表达式示例非常相似。但是,它无法在 g++ 6.2 下编译。它确实可以用 clang++ 6.0 编译,但会产生错误的结果。

boost版本是1.63。 看来我有一些“移动”或初始化问题。

#include <iostream>
#include <list>
#include <vector>
#include <utility> 

#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/fusion/include/io.hpp>

namespace ns
{
  namespace ast
  {
    namespace x3 = boost::spirit::x3;

    // forward definition
    class uintObj;
    struct varVec;

    // define type
    using uintPair_t = std::pair<unsigned int, unsigned int>;
    using uintVec_t = std::vector<uintObj>;

    // general token value:
    class uintObj : public x3::variant <
      unsigned int,
      uintPair_t
      >
    {
     public:
      using base_type::base_type;
      using base_type::operator=;
    };

    struct varVec
    {
      uintVec_t valVector;
    };
  }
}

BOOST_FUSION_ADAPT_STRUCT(
  ns::ast::varVec,
  valVector
  )

namespace ns
{
  namespace parser
  {
    // namespace x3 = boost::spirit::x3;
    // using namespace x3;
    using namespace boost::spirit::x3;

    // definition of the range pair:
    rule<class uintPair, ast::uintPair_t> const uintPair = "uintPair";

    auto const uintPair_def =
      uint_
      >> '-'
      >> uint_
      ;

    rule<class uintObj, ast::uintObj> const uintObj = "uintObj";

    auto const uintObj_def =
      uint_
      | uintPair
      ;

    // define rule definition : rule<ID, attrib>
    // more terse definition :
    // struct varVec_class;
    // using varVec_rule_t = x3::rule<varVec_class, ast::varVec>;
    // varVec_rule_t const varVec = "varVec";
    // varVec is the rule, "varVec" is the string name of the rule.
    rule<class varVec, ast::varVec> const varVec = "varVec";

    auto const varVec_def =
      '['
      >> uintObj % ','
      >> ']'
      ;

    BOOST_SPIRIT_DEFINE(
      varVec,
      uintObj,
      uintPair
      );
  }
}

int main()
{
  std::string input ("[1, 11, 3, 6-4]\n");
  std::string::const_iterator begin = input.begin();
  std::string::const_iterator end = input.end();

  ns::ast::varVec result;                 // ast tree
  using ns::parser::varVec;               // grammar
  using boost::spirit::x3::ascii::space;

  bool success = phrase_parse(begin, end, varVec, space, result);

  if (success && begin == end)
    std::cout << "good" << std::endl;
  else
    std::cout << "bad" << std::endl;

  return 0;
}

最佳答案

交换 uintObj_def 的替代顺序

auto const uintObj_def =
    uintPair
  | uint_
  ;

您现在的公式将始终与 uint_ 匹配,因为 uintPair 以有效的 uint_ 开头。

关于c++ - boost spirit x3 变体和 std::pair,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53489465/

相关文章:

c++ - 用于 NTLM 身份验证的 GSSAPI

c++ - 为什么算法在第一个条件后结束?

c++ - 空间跳跃对灵气不起作用

c++ - Boost.Spirit将表达式转换为AST

c++ - Boost Spirit Qi 语法用于合成关联二元运算符 AST 节点?

C++ 复制构造函数复制等级

c++ - std::async 函数串行运行

c++ - 人们说 C++ 有 "undecidable grammar"是什么意思?

c++ - 振奋精神,推进申报问题

c++ - 如何使用 boost::spirit 将文本解析为结构?