gpt4 book ai didi

c++ - 替代属性综合和 AST 设计

转载 作者:行者123 更新时间:2023-11-30 03:25:09 25 4
gpt4 key购买 nike

在下面的语法中,当我将替代项(| 属性)添加到开始规则时,出现此错误

'boost::spirit::x3::traits::detail::move_to': none of the 3 overloads could convert all the argument types e:\data\boost\boost_1_65_1\boost\spirit\home\x3\support\traits\move_to.hpp 180

我怀疑问题是 property 属性是一个结构,而 property_list 是一个 vector (x3 不应该创建一个条目的 vector 吗?)。设计 AST 结构以支持替代方案的推荐方法是什么? Boost 变体?

#include <string>
#include <vector>
#include <iostream>
#include <iomanip>
#include <map>

#pragma warning(push)
#pragma warning(disable : 4348)
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/variant.hpp>
#include <boost/fusion/adapted/struct.hpp>
#pragma warning(pop)

namespace x3 = boost::spirit::x3;

namespace scl_ast
{

struct KEYWORD : std::string
{
using std::string::string;
using std::string::operator=;
};

struct NIL
{
};

using VALUE = boost::variant <NIL, std::string, int, double, KEYWORD>;

struct PROPERTY
{
KEYWORD name;
VALUE value;
};

static inline std::ostream& operator<< (std::ostream& os, VALUE const& v)
{
struct
{
std::ostream& _os;

void operator () (std::string const& s) const { _os << std::quoted (s); }
void operator () (int i) const { _os << i; }
void operator () (double d) const { _os << d; }
void operator () (KEYWORD const& k) const { _os << k; }
void operator () (NIL) const { }
} vis { os };

boost::apply_visitor (vis, v);
return os;
}

static inline std::ostream& operator<< (std::ostream& os, PROPERTY const& prop)
{
os << prop.name;

if (prop.value.which ())
{
os << "=" << prop.value;
}

return os;
}

static inline std::ostream& operator<< (std::ostream& os, std::vector <PROPERTY> const& props)
{
for (auto const& prop : props)
{
os << prop << " ";
}

return os;
}

}; // End namespace scl_ast

BOOST_FUSION_ADAPT_STRUCT (scl_ast::PROPERTY, name, value)

//
// Keyword-value grammar for simple command language
//

namespace scl
{
using namespace x3;


auto const keyword = rule <struct _keyword, std::string> { "keyword" }
= lexeme [+char_ ("a-zA-Z0-9$_")];

auto const quoted_string
= lexeme ['"' >> *('\\' > char_ | ~char_ ('"')) >> '"'];

auto const value
= quoted_string
| x3::real_parser<double, x3::strict_real_policies<double>>{}
| x3::int_
| keyword;

auto const property = rule <struct _property, scl_ast::PROPERTY> { "property" }
= keyword >> -(("=" >> value));

auto const property_list = rule <struct _property_list, std::vector <scl_ast::PROPERTY>> { "property_list" }
= lit ('(') >> property % ',' >> lit (')');

auto const start = skip (blank) [property_list | property];

}; // End namespace scl


int
main ()

{
std::vector <std::string> input =
{
"(abc=1.,def=.5,ghi=2.0)",
"(ghi = 1, jkl = 3)",
"(abc,def=1,ghi=2.4,jkl=\"mno 123\", pqr = stu)",
"(abc = test, def, ghi=2)",
"abc=1",
"def = 2.7",
"ghi"
};


for (auto const& str : input)
{
std::vector <scl_ast::PROPERTY> result;
auto b = str.begin (), e = str.end ();


bool ok = x3::parse (b, e, scl::start, result);
std::cout << (ok ? "OK" : "FAIL") << '\t' << std::quoted (str) << std::endl;

if (ok)
{
std::cout << " -- Parsed: " << result << std::endl;

if (b != e)
{
std::cout << " -- Unparsed: " << std::quoted (std::string (b, e)) << std::endl;
}

}

std::cout << std::endl;
} // End for

return 0;
} // End main

最佳答案

I suspect that the problem is that the property attribute is a struct, and property_list is a vector (shouldn't x3 create a vector of one entry?)

是的,是的,是的,视情况而定。

我大致看到了 3 种方法来解决这个问题。让我们从简单的开始:

  1. 类似 Force Container 的合成: Live On Coliru

    = skip(blank)[property_list | repeat(1)[property] ];
  2. 强制属性类型。原来我在这里错了:它曾经对 Qi 有效,但显然已经被删除了。在这里,不工作和所有:

    auto coerce = [](auto p) { return rule<struct _, std::vector<scl_ast::PROPERTY> > {} = p; };

    auto const start
    = skip(blank)[property_list | coerce(property)];
  3. 第三个实际上没有实际意义,因为同样的问题。所以我想我欠你一个人为的解决方法,使用语义操作: Live On Coliru

    auto push_back = [](auto& ctx) {
    _val(ctx).push_back(_attr(ctx));
    };

    auto const start
    = rule<struct _start, std::vector<scl_ast::PROPERTY>, true>{ "start" }
    = skip(blank)[property_list | omit[property[push_back]]];

关于c++ - 替代属性综合和 AST 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49201904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com