为什么这不编译?(评论r3将编译,但我希望在规则中使用分号)
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <string>
#include <vector>
struct v
{
std::string value;
};
BOOST_FUSION_ADAPT_STRUCT
(
v,
(std::string, value)
)
using namespace boost::spirit::x3;
auto r1 = rule<struct s1, std::string>{} = lexeme[+alpha];
auto r2 = rule<struct s2, v>{} = r1;
using ast = std::vector<v>;
auto r3 = rule<struct s3, ast>{} = *(r2 >> ';');
//auto r3 = rule<struct s3, ast>{} = *r2;
int main()
{
std::string script("a;");
auto begin = script.begin();
auto end = script.end();
ast a;
phrase_parse(begin, …Run Code Online (Sandbox Code Playgroud) 我是C++和Boost Spirit X3的新手.对于我的项目,我将两个文件中的地理社交图解析为具有以下结构,其中boost boost X3为boost图.
我有一个有效的实施.由于我之前没有任何图书馆的经验,我想知道你对这种方法的看法,以及你是否建议采取不同的方法.
在图形文件中,每条边有一条线.解析边缘时,我必须创建图形的节点,以防以前没有看到节点.我使用语义操作,每次遇到node-id时都会检查该节点是否已经在图中.阅读完一行后,我使用语义动作然后添加边缘.
在位置文件中,在给定时间每个节点的已知位置有一行.我存储了图中节点已知的第一个位置(使用自定义boost图属性).
我必须提出具体问题,但很乐意接受任何想法和建议:
图表(表示图中的边)
[user1] [user2]
0 3
Run Code Online (Sandbox Code Playgroud)
地点
[user] [check-in time] [latitude] [longitude] [location id]
0 2010-10-19T23:55:27Z 30.2359091167 -97.7951395833 22847
Run Code Online (Sandbox Code Playgroud)
Spirit X3解析代码
// Parse the gowalla edge file
boost::spirit::istream_iterator file_iterator(edge_file), eof;
x3::phrase_parse(file_iterator, eof,
// Begin grammar
(
*((x3::int_[add_vertex] >> x3::int_[add_vertex])[add_edge])
),
// End grammar
x3::space
);
// Fail if we couldn't parse the whole edges file
if (file_iterator != eof) {
std::cerr << "Couldn't parse whole edges file" << …Run Code Online (Sandbox Code Playgroud) 如何使用boost.spirit x3解析为如下结构:
struct person{
std::string name;
std::vector<std::string> friends;
}
Run Code Online (Sandbox Code Playgroud)
来自boost.spirit v2我会使用语法,但由于X3不支持语法,我不知道如何干净.
编辑:如果有人可以帮我编写一个解析字符串列表的解析器并返回一个person第一个字符串是名称并且字符串的res在friends向量中,那将是很好的.
我正在努力编写一个标识符解析器,它解析一个不是关键字的字母字符串。关键字都在一个表中:
struct keywords_t : x3::symbols<x3::unused_type> {
keywords_t() {
add("for", x3::unused)
("in", x3::unused)
("while", x3::unused);
}
} const keywords;
Run Code Online (Sandbox Code Playgroud)
标识符的解析器应该是这样的:
auto const identifier_def =
x3::lexeme[
(x3::alpha | '_') >> *(x3::alnum | '_')
];
Run Code Online (Sandbox Code Playgroud)
现在我尝试将这些组合起来,以便标识符解析器在解析关键字时失败。我是这样试的:
auto const identifier_def =
x3::lexeme[
(x3::alpha | '_') >> *(x3::alnum | '_')
]-keywords;
Run Code Online (Sandbox Code Playgroud)
和这个:
auto const identifier_def =
x3::lexeme[
(x3::alpha | '_') >> *(x3::alnum | '_') - keywords
];
Run Code Online (Sandbox Code Playgroud)
它适用于大多数输入,但如果字符串以关键字开头,例如int, whilefoo, forbar解析器无法解析此字符串。我怎样才能让这个解析器正确?
我目前正在使用boost spirit X3为我的DSL实现表达式和运算符层次结构.
我认为我的解析器在语义上是正确的,但是当我尝试编译它时,在编译时,gcc和clang具有巨大的内存占用,编译了无限的时间,然后退出"g ++:内部编译器错误:已杀死(程序cc1plus) )".
我试图最小化表达式解析器的代码,但它不是那么简单
这是一个演示.
有人能告诉我这里我做错了什么,或者这是一个错误?
编辑:我认为问题是那里的问题:
auto const idx = as<ast::Operation>(helper::idxaccess_op > expression > ']');
auto const func = as<ast::Operation>(helper::func_call_op > expression%',' > ')');
auto const data = as<ast::Operation>(helper::access_op > expression);
auto const func_call_expr_def =
primary_expr >> *(idx|func|data);
Run Code Online (Sandbox Code Playgroud)
如果我(idx|func|data)改为(idx|func),它也会永久编译并使用高达16GB的ram,但gcc能够编译它,并且解析器的工作原理如何.
编辑二:请看看上面的链接有我的例子导致错误.
我是currentyl试图将我的提升精神x3解析器分成不同的_def和.cpp文件使用BOOST_SPIRIT_DEFINE/DECLARE/INSTANTIATE,但我不断收到链接错误.
这里是我的解析器分离.
链接器错误读取
<artificial>:(.text.startup+0xbb): undefined reference to `bool kyle::parser::impl::parse_rule<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::space_tag> const, boost::spirit::x3::unused_type>, boost::spirit::x3::unused_type const>(boost::spirit::x3::rule<kyle::parser::impl::identifier_class, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, false>, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, boost::spirit::x3::context<boost::spirit::x3::skipper_tag, boost::spirit::x3::char_class<boost::spirit::char_encoding::standard, boost::spirit::x3::space_tag> const, boost::spirit::x3::unused_type> const&, boost::spirit::x3::unused_type const&)'
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我怎样才能让我的例子有效?
config.hpp:
#include <boost/spirit/home/x3.hpp>
namespace kyle{
namespace parser{
namespace x3 = boost::spirit::x3;
typedef std::string::const_iterator iterator_type;
typedef x3::phrase_parse_context<x3::ascii::space_type>::type context_type;
}
}
Run Code Online (Sandbox Code Playgroud)literals.cpp:
#include "literals_def.hpp"
#include "config.hpp"
#include <boost/spirit/home/x3.hpp>
namespace kyle { …Run Code Online (Sandbox Code Playgroud)Spirit X3解析器函数使用1 attribut可以很好地工作.当我尝试使用多个属性编译文档中的代码时,它不起作用.
#include <boost/spirit/home/x3.hpp>
#include <iostream>
using namespace std;
using namespace boost::spirit;
string a = "3.2 4.5";
auto begin = a.begin();
auto end = a.end();
double d1 = 0.0, d2 = 0.0;
x3::phrase_parse(begin, end ,
x3::double_ >> x3::double_,
x3::space,
d1, d2); // doesn't work. Accept only 1 attribut
Run Code Online (Sandbox Code Playgroud)
它返回以下错误:
/home/sacha/Dev/vql/vqlcompiler.cpp:20: erreur : no matching function for call to ‘phrase_parse(__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >&, boost::spirit::x3::sequence<boost::spirit::x3::real_parser<double>, boost::spirit::x3::real_parser<double> >, const space_type&, double&, double&)’
x3::double_ >> x3::double_, x3::space, d1, d2); …Run Code Online (Sandbox Code Playgroud) 我正在和一个朋友为一个小型个人项目做翻译;我们开始实现所有的类和一般结构,在这些结构中代码将被翻译,然后执行只是为了将实际的解析代码推迟到这些结构中。
现在我们必须构建解析器,经过一番搜索,我发现到处都是关于灵气和灵气 X3 的帖子和人,好像它们是(我认为它们是)两种不同的方式来制作解析器,但没有一个说不同,哪个更近,我应该从哪个开始。
目的是,给定一个代码字符串,输出最终错误,如果一切都遵守语法和逻辑,则将代码转换为我们已经构建的类的树。我们想在解析过程中检查一致性,例如“您正在使用未声明的变量”类型的错误。
我不确定这两个库如何以不同的方式对待事物。
我想解析CSS颜色函数(为简单起见,所有参数都是0到255之间的数字)
rgb(r,g,b)
rgba(r,g,b,a)
hsl(h,s,l)
hsla(h,s,l,a)
Run Code Online (Sandbox Code Playgroud)
成
struct color
{
color(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a) : red{r}, green{g}, blue{b}, alpha{a} {}
static color hsl(std::uint8_t h, std::uint8_t s, std::uint8_t l, std::uint8_t a) { ... }
std::uint8_t red;
std::uint8_t green;
std::uint8_t blue;
std::uint8_t alpha;
}
Run Code Online (Sandbox Code Playgroud)
我有一个工作hsl函数实现,它将h,s和l转换为rgb值.
我还要rule处理前两个函数:
constexpr auto uint8 = uint_parser<std::uint8_t>{};
const auto color_rgb = rule<struct rgb, color>{"rgb"}
= lit("rgb") >> '(' >> uint8 >> ',' >> uint8 >> ',' >> uint8 >> ')' >> …Run Code Online (Sandbox Code Playgroud) 我正在研究 Boost Spirit X3,但正在努力完全掌握语义操作中使用x3::_val和之间的区别x3::_attr,以从传递的上下文中提取属性。官方文档指出
_val:对直接或间接调用解析器 p 的最内层规则的属性的引用
_attr:对解析器 p 的属性的引用
这对我没什么帮助。我研究了一些并偶然发现了/sf/answers/4319223961/,其中指出
x3::_val(ctx) 类似于 qi::_val
x3::_attr(ctx) 类似于 qi::_0 (对于简单解析器则为 qi::_1)
但不幸的是,我没能弄清楚什么qi::_val和qi::_0/qi::_1,或者更准确地说它们的区别是什么。
最后,我还找到了/sf/answers/3778032191/,其中指出
它们在
x3::_val特定x3::_attr情况下的情况取决于 make_attribute/transform_attribute 特征。默认情况下,它们将引用相同的值,直到您具有具有不同属性类型的嵌套规则
这似乎与我迄今为止进行的实验一致——除了我还没有设法_attr并_val产生不同的值。
尽管我还无法理解它们的区别,但它似乎与我见过的所有示例相当相关,使用语义动作来计算给定计算的结果(参见例如此处)似乎总是用作_attr更全局的状态,而_val似乎是刚刚解析的事物的即时状态。例如
[](auto& ctx) { _val(ctx) = _val(ctx) * _attr(ctx); }
Run Code Online (Sandbox Code Playgroud)
然而,尽管如此,我仍然不太能够指出这两个属性之间语义上的确切差异。有人可能会尝试重新表述 Boost 的文档并举一个例子来说明差异实际上很重要/可见吗?
boost-spirit-x3 ×10
c++ ×9
boost-spirit ×8
boost ×4
c++14 ×4
boost-graph ×1
c++17 ×1
css ×1
parsing ×1