gpt4 book ai didi

c++ - 将输入映射到增强精神中的 ast 类型

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

我想对输入给定精神语法的输入字符串进行颜色突出显示。是否有一种简单的(或任何,如果不容易的话)方法将给定字符从输入映射到它匹配的规则/ast 类型?最好采用规则/ast 类型的数组/vector 的形式,其中索引是输入字符串的字符索引。或者可能更好——迭代器对 ast 类型狂暴。

最佳答案

当然有。本网站上的几个答案展示了类似的事情。您必须决定要如何处理子规则。

使用 on_success 的随机示例:

Live On Coliru

//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <iomanip>
namespace qi = boost::spirit::qi;

using It = std::string::const_iterator;
using R = boost::iterator_range<It>;
using RuleId = void const*;

struct token {
R what;
RuleId r_id;
};

struct assocociate_f {
std::vector<token>& into;
RuleId r_id = nullptr;

template <typename Ctx>
void operator()(qi::unused_type, Ctx& ctx) const {
using boost::fusion::at_c;
into.push_back({at_c<0>(ctx.attributes), r_id});
}
};

int main() {
qi::rule<It, R()> numlit, ident, oper;
qi::rule<It, R(), qi::space_type> simple, expr;

numlit = qi::raw[qi::double_];
ident = qi::raw[qi::lexeme[qi::alpha >> *qi::alnum]];
simple = qi::raw[(numlit | ident | '(' >> expr >> ')')];
oper = qi::raw[qi::char_("-+*/%")];
expr = qi::raw[simple >> *(oper >> expr)];

std::vector<token> collect;
qi::on_success(numlit, assocociate_f{collect, &numlit});
qi::on_success(ident, assocociate_f{collect, &ident});
qi::on_success(oper, assocociate_f{collect, &oper});
//qi::on_success(simple, assocociate_f{collect, &simple});
//qi::on_success(expr, assocociate_f{collect, &expr});

BOOST_SPIRIT_DEBUG_NODES((numlit)(ident)(simple)(expr));

auto idof = [&](token const& tok) -> std::string {
auto match = [&](auto const& x) { return tok.r_id == static_cast<void const*>(&x); };
if (match(numlit)) return "numeric literal";
if (match(ident)) return "identifier";
if (match(simple)) return "simple expression";
if (match(expr)) return "expression";
if (match(oper)) return "operator";
return "other";
};

for (std::string const input : { "3 * pi + (13/47 - 5)" }) {
std::cout << std::setw(20) << "input: " << input << "\n";
It f = input.begin(), l = input.end();

if (qi::phrase_parse(f, l, expr, qi::space)) {
for (auto& tok : collect) {
std::cout
<< std::setw(20) << idof(tok) + ": "
<< std::setw(tok.what.begin() - input.begin() + 1) << tok.what
<< "\n";
}
} else {
std::cout << "Parse failed\n";
}

if (f!=l) {
std::cout << "Remaining: '" << std::string(f,l) << "'\n";
}
}
}

打印

             input: 3 * pi + (13/47 - 5)
numeric literal: 3
operator: *
identifier: pi
operator: +
numeric literal: 13
operator: /
numeric literal: 47
operator: -
numeric literal: 5

取消注释额外内容

//qi::on_success(simple, assocociate_f{collect, &simple});
//qi::on_success(expr, assocociate_f{collect, &expr});

你得到: Live On Coliru

             input: 3 * pi + (13/47 - 5)
numeric literal: 3
simple expression: 3
operator: *
identifier: pi
simple expression: pi
operator: +
numeric literal: 13
simple expression: 13
operator: /
numeric literal: 47
simple expression: 47
operator: -
numeric literal: 5
simple expression: 5
expression: 5
expression: 47 - 5
expression: 13/47 - 5
simple expression: (13/47 - 5)
expression: (13/47 - 5)
expression: pi + (13/47 - 5)
expression: 3 * pi + (13/47 - 5)

更多

一个更时髦的例子是 How to provider user with autocomplete suggestions for given boost::spirit grammar? - 使用 string_viewstring_ref 而不是 iterator_range。此外,这会“折叠”相邻范围以产生更多可用范围。

其他相关例子:

关于c++ - 将输入映射到增强精神中的 ast 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51252725/

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