boost-spirit 相关问题

Boost.Spirit是一组用于解析和输出生成的C ++库,使用表达式模板和模板元编程实现为域特定嵌入式语言(DSEL)。 Spirit库使目标语法能够专门用C ++编写。内联语法规范可以与其他C ++代码自由混合,并且由于C ++模板的生成能力,可以立即执行。

如何在 Boost::Spirit::x3 中执行通用的可重用规则?

在我目前正在开发的解析器中,我正在编写一些规则/“子解析器”,其大小相当重要。问题是:因为这个解析器可能需要编译器付出一定的努力......

回答 1 投票 0

使用 Boost Spirit 查找字符串中的孤立单词

我是个新手,也许这甚至是很容易得到的东西。 但是,编写 boost::spirit 解析器的最佳方法是什么?该解析器允许您仅在单词是孤立的情况下才匹配字符串中的单词? 示例...

回答 1 投票 0

如何修复成员运算符 boost 词法解析器的错误 ->*

感谢任何帮助。我正在编写一个解析器,它可以与 GCC 4.9.3 + Boost 1_55 及更早版本一起使用,但不能与 Boost(或 GCC)的更高版本一起使用。 错误是: 错误:与“operator->”不匹配(操作数 t...

回答 1 投票 0

boost::spirit::错误:'struct xxx'中没有名为'value_type'的类型

我正在尝试我的第一个精神解析器,似乎我遇到了属性传播问题。尝试 plantuml 语法。如果我破解它就该死,如果我不破解就该死...... 完整要点是

回答 1 投票 0

使用 boostspirit 识别带双括号的令牌字符串时遇到问题

解析字符串时: 1815 ((sd-pam)) S 1778 1778 1778 ... 我试图省略“((sd-pam))”标记 我使用了以下内容: omit_string %= lexeme['(' >> +(char_ - ')') >> '...

回答 1 投票 0

使用 Boost Spirit 将 INI 文件解析为结构时出现问题

我正在尝试使用以下代码将 INI 文件信息存储在结构中: #包括 #包括 #包括 #我...

回答 1 投票 0

使用 Boost.Spirit 解析 INI 部分时出现问题

我正在为一个大学项目研究解析器。我发现了 Boost.Spirit 并决定使用它。在阅读其文档并实现一些基本示例后,我尝试制作一个解析器

回答 1 投票 0

Boost Spirit x3:解析向量,但仅有条件地将项目放入结果

考虑 (int ":" int )* 形式的字符串。我想按以下方式将这样的字符串解析为整数向量:如果第二个值是奇数,则将第一个值添加到结果中。其他...

回答 1 投票 0

在 Boost Spirit 中解析后跟可变数量整数的字符

我正在尝试解析以下形式的字符串: f 1 2 3 4 f 1 2 3 f 1 2 3 4 5 使用增强精神,我有: 使用 boost::spirit::qi::uint_; 使用 boost::spirit::qi::double_; 使用 boost::spirit::qi::_1; 你...

回答 1 投票 0

使用 boost::spirit::x3 v1.84 编译错误

请注意,此代码在 boost v1.69 的spirit x3 上编译时没有错误,该代码最初是为此开发的。错误起源于 x3::parse() 行,但使用此模板噪声......

回答 1 投票 0

Boost Spirit X3 中属性类别的模板实例化不明确

我正在为计算器编写一个简单的解析器,我希望有一个变体运算符作为参数传递来构造表达式。 #包括 #

回答 1 投票 0

使用 boost::spirit::x3 进行 URL 解析

我正在尝试使用 boost::spirit::x3 将 URL 解析和分解为多个部分,如下所示: #包括 #包括 #包括 我正在尝试使用 boost::spirit::x3 将 URL 解析和分解为多个部分,如下所示: #include <iostream> #include <boost/fusion/adapted/std_tuple.hpp> #include <boost/fusion/adapted/struct.hpp> #include <boost/spirit/home/x3.hpp> struct UrlParts { std::string prefix, host, suffix; }; BOOST_FUSION_ADAPT_STRUCT(UrlParts, prefix, host, suffix) UrlParts parseSpirit(std::string_view input) { namespace x3 = boost::spirit::x3; static const auto scheme_ = (x3::raw[+x3::char_("a-zA-Z0-9+.-") >> "://"]); static const auto userinfo_ = (x3::raw[+~x3::char_("@") >> "@"]); static const auto prefix_ = (-scheme_ >> -userinfo_); static const auto port_ = (x3::raw[':' >> -x3::repeat(1, 5)[x3::digit] >> &(x3::char_("/?#") | x3::eoi)]); static const auto host_ = (+(x3::char_("a-fxXA-F0-9:.") - port_)); static const auto path_ = (x3::char_("/?#") >> *x3::char_); // to store path+query+fragment static const auto suffix_ = (-port_ >> -path_); //static const auto url = x3::rule<class url, UrlParts>() = -prefix_ >> ('[' >> host_ >> ']' | host_) >> -suffix_; static const auto url = -prefix_ >> ('[' >> host_ >> ']' | host_) >> -suffix_; // prefix & suffix are optional but host is required // BOOST_SPIRIT_DEBUG_NODES((scheme_)(userinfo_)(host_)(port_)(path_)(url)); // Parse the input auto iter = input.begin(); auto end = input.end(); UrlParts parts; auto attr = std::tie(parts.prefix, parts.host, parts.suffix); //parse(input.begin(), input.end(), x3::eps >> url >> x3::eoi, parts); bool ret = x3::parse(iter, end, url >> x3::eoi, attr); if (!ret) { std::cout << "Parsing failed" << std::endl; } return parts; } int main() { for (auto input : {"http://usr:[email protected]:8080/file.php?abc=1#23", "http://[::ffff:192.168.1.1]:8080/file.php?abc=1#23", "http://::ffff:192.168.1.1/file.php?abc=1#23", "::ffff:192.168.1.1" }) { std::cout << "Input: " << input << std::endl; auto parts = parseSpirit("http://usr:[email protected]/file.php?abc=1"); std::cout << "Output: Prefix: " << parts.prefix << ", Host: " << parts.host << ", Suffix: " << parts.suffix << std::endl; std::cout << "================" << std::endl; } return 0; } 但是上面的代码无法编译并出现错误: /usr/include/boost/spirit/home/x3/operator/detail/sequence.hpp:140:25: error: static assertion failed: Size of the passed attribute is less than expected. 140 | actual_size >= expected_size | ~~~~~~~~~~~~^~~~~~~~~~~~~~~~ /usr/include/boost/spirit/home/x3/operator/detail/sequence.hpp:140:25: note: ‘(((int)boost::spirit::x3::detail::partition_attribute >, boost::spirit::x3::literal_string > > >, boost::spirit::x3::optional > >, boost::spirit::x3::literal_char > > > > >, boost::spirit::x3::alternative, boost::spirit::x3::plus, boost::spirit::x3::raw_directive, boost::spirit::x3::optional, boost::spirit::x3::detail::finite_count > > >, boost::spirit::x3::and_predicate, boost::spirit::x3::eoi_parser> > > > > > >, boost::spirit::x3::literal_char >, boost::spirit::x3::plus, boost::spirit::x3::raw_directive, boost::spirit::x3::optional, boost::spirit::x3::detail::finite_count > > >, boost::spirit::x3::and_predicate, boost::spirit::x3::eoi_parser> > > > > > > >, boost::spirit::x3::optional, boost::spirit::x3::optional, boost::spirit::x3::detail::finite_count > > >, boost::spirit::x3::and_predicate, boost::spirit::x3::eoi_parser> > > > >, boost::spirit::x3::optional, boost::spirit::x3::kleene > > > > >, std::tuple, std::allocator >&, std::__cxx11::basic_string, std::allocator >&, std::__cxx11::basic_string, std::allocator >&>, boost::spirit::x3::unused_type, void>::actual_size) >= ((int)boost::spirit::x3::detail::partition_attribute >, boost::spirit::x3::literal_string > > >, boost::spirit::x3::optional > >, boost::spirit::x3::literal_char > > > > >, boost::spirit::x3::alternative, boost::spirit::x3::plus, boost::spirit::x3::raw_directive, boost::spirit::x3::optional, boost::spirit::x3::detail::finite_count > > >, boost::spirit::x3::and_predicate, boost::spirit::x3::eoi_parser> > > > > > >, boost::spirit::x3::literal_char >, boost::spirit::x3::plus, boost::spirit::x3::raw_directive, boost::spirit::x3::optional, boost::spirit::x3::detail::finite_count > > >, boost::spirit::x3::and_predicate, boost::spirit::x3::eoi_parser> > > > > > > >, boost::spirit::x3::optional, boost::spirit::x3::optional, boost::spirit::x3::detail::finite_count > > >, boost::spirit::x3::and_predicate, boost::spirit::x3::eoi_parser> > > > >, boost::spirit::x3::optional, boost::spirit::x3::kleene > > > > >, std::tuple, std::allocator >&, std::__cxx11::basic_string, std::allocator >&, std::__cxx11::basic_string, std::allocator >&>, boost::spirit::x3::unused_type, void>::expected_size))’ evaluates to false 有什么问题的建议吗?与 boost::spirit::qi 类似的代码可以正常工作。 此外,我有兴趣了解是否有更有效的方法来执行此操作,例如:使用 string_view 而不是 string,因为所有 3 个部分都存在于输入视图中。 预先感谢! 这意味着属性未被检测为与解析器表达式兼容。看到它在 1.76 中被破坏了: 我看到的第一个问题是尝试从两个 prefix 指令合成单个字符串 (raw[])。那是...行不通的。 好消息是它可以(再次?)从 1.77 开始,但总的来说,考虑对属性兼容性更明确一点,就像这个答案中的 as_type 理解 Boost.Spirit 中的列表运算符 (%) ,或许多其他https://stackoverflow.com/search?tab=newest&q=user%3a85371%20x3%20as_type&searchOn=3,甚至更多,如果你寻找我通常更喜欢的名字as...... https://stackoverflow.com/search?q=user%3A85371+x3+as+x3%3A%3Arule 也就是说,当我查看你的代码时,你绑定了一个手动绑定的元组AND不知何故仍然适应结构?那是多余的。我假设您只想手动绑定,所以放弃适应。 接下来,无论如何,不要使用解析器组合器库作为标记器。即,不要随机地将不相关的产品组合在一起(后缀确实不应包含端口规范)。 此外,使用整数解析器解析为真实的端口号。当然,如果您无论如何都要“迂腐”地严格限制允许的位数!请看这里: auto portnum_ = x3::uint_parser<uint16_t, 10, 1, 5>{}; auto portspec_ = ':' >> portnum_ >> &(x3::char_("/?#") | x3::eoi); 小心双重可选性。例如。由于 suffix_ = -port_ >> -path_ 从字面上看只有可选元素,因此表达式 -suffix_ 充其量与 suffix_ 具有相同的含义。但是,在很多情况下(可选的重复结构),您将获得零长度匹配的无限循环。我想/或#也应该结束用户信息的产生。并非所有事情都需要raw。例如。我更愿意auto userinfo_ = +~x3::char_("@/#") >> x3::char_("@"); 用于用户信息。事实上,如果你这样做 auto authority_ = ('[' >> host_ >> ']' | host_) >> -portspec_; 您将正确获取解析后的主机,无需使用 [] 括号,该括号仅在 URI 语法中有意义。您已注释掉输入结束验证,让我们重新启用它们。我们还返回更多丰富的信息(包括 valid 标志)和更多测试用例:实时编译器资源管理器 #include <boost/fusion/adapted/std_tuple.hpp> #include <boost/spirit/home/x3.hpp> #include <iostream> struct UrlParts { std::string prefix, host, suffix; }; UrlParts parseSpirit(std::string_view input) { namespace x3 = boost::spirit::x3; auto scheme_ = x3::raw[+x3::char_("a-zA-Z0-9+.-") >> "://"]; auto userinfo_ = x3::raw[+~x3::char_("@") >> "@"]; auto prefix_ = scheme_ >> -userinfo_; auto port_ = x3::raw[':' >> -x3::repeat(1, 5)[x3::digit] >> &(x3::char_("/?#") | x3::eoi)]; auto host_ = +(x3::char_("a-fxXA-F0-9:.") - port_); auto path_ = x3::char_("/?#") >> *x3::char_; // to store path+query+fragment auto suffix_ = -port_ >> -path_; // static const auto url = = -prefix_ >> ('[' >> host_ >> ']' | host_) >> // -suffix_; auto url // //= x3::rule<class url, UrlParts>() // = -prefix_ // //>> ('[' >> host_ >> ']' | host_) >> // -suffix_ // prefix & suffix are optional but host is required ; // Parse the input auto iter = input.begin(); auto end = input.end(); UrlParts p; auto attr = std::tie(p.prefix/*, p.host, p.suffix*/); bool ret = x3::parse(iter, end, url >> x3::eoi, attr); if (!ret) { std::cout << "Parsing failed" << std::endl; } return p; } int main() { for (auto input : {"http://usr:[email protected]:8080/file.php?abc=1#23", "http://[::ffff:192.168.1.1]:8080/file.php?abc=1#23", "http://::ffff:192.168.1.1/file.php?abc=1#23", "::ffff:192.168.1.1"}) { std::cout << "Input: " << input << std::endl; auto parts = parseSpirit("http://usr:[email protected]/file.php?abc=1"); std::cout << "Output: Prefix: " << parts.prefix << ", Host: " << parts.host << ", Suffix: " << parts.suffix << std::endl; std::cout << "================" << std::endl; } } 印刷 192.168.1.1 {true, "", "", "192.168.1.1", "", unspecified} 192.168.1.1/ {true, "", "", "192.168.1.1", "/", unspecified} 192.168.1.1/file.php {true, "", "", "192.168.1.1", "/file.php", unspecified} 192.168.1.1/file.php?abc=1 {true, "", "", "192.168.1.1", "/file.php?abc=1", unspecified} 192.168.1.1:8888 {true, "", "", "192.168.1.1", "", 8888} 192.168.1.1:8888/ {true, "", "", "192.168.1.1", "/", 8888} 192.168.1.1:8888/file.php {true, "", "", "192.168.1.1", "/file.php", 8888} 192.168.1.1:8888/file.php?abc=1 {true, "", "", "192.168.1.1", "/file.php?abc=1", 8888} ::ffffff::192.168.1.1:9999/file.php?abc=1 {true, "", "", "::ffffff::192.168.1.1", "/file.php?abc=1", 9999} http://192.168.1.1 {true, "http://", "", "192.168.1.1", "", unspecified} http://192.168.1.1/ {true, "http://", "", "192.168.1.1", "/", unspecified} http://192.168.1.1/file.php {true, "http://", "", "192.168.1.1", "/file.php", unspecified} http://192.168.1.1/file.php?abc=1 {true, "http://", "", "192.168.1.1", "/file.php?abc=1", unspecified} http://192.168.1.1:8888 {true, "http://", "", "192.168.1.1", "", 8888} http://192.168.1.1:8888/ {true, "http://", "", "192.168.1.1", "/", 8888} http://192.168.1.1:8888/file.php {true, "http://", "", "192.168.1.1", "/file.php", 8888} http://192.168.1.1:8888/file.php?abc=1 {true, "http://", "", "192.168.1.1", "/file.php?abc=1", 8888} http://::ffffff::192.168.1.1:9999/file.php?abc=1 {true, "http://", "", "::ffffff::192.168.1.1", "/file.php?abc=1", 9999} http://[email protected] {true, "http://", "sehe@", "192.168.1.1", "", unspecified} http://[email protected]/ {true, "http://", "sehe@", "192.168.1.1", "/", unspecified} http://[email protected]/file.php {true, "http://", "sehe@", "192.168.1.1", "/file.php", unspecified} http://[email protected]:8888 {true, "http://", "sehe@", "192.168.1.1", "", 8888} http://[email protected]:8888/ {true, "http://", "sehe@", "192.168.1.1", "/", 8888} http://[email protected]:8888/file.php {true, "http://", "sehe@", "192.168.1.1", "/file.php", 8888} http://usr:[email protected]/file.php?abc=1 {true, "http://", "usr:pwd@", "192.168.1.1", "/file.php?abc=1", unspecified} [email protected] {true, "", "sehe@", "192.168.1.1", "", unspecified} [email protected]/ {true, "", "sehe@", "192.168.1.1", "/", unspecified} [email protected]/file.php {true, "", "sehe@", "192.168.1.1", "/file.php", unspecified} [email protected]:8888 {true, "", "sehe@", "192.168.1.1", "", 8888} [email protected]:8888/ {true, "", "sehe@", "192.168.1.1", "/", 8888} [email protected]:8888/file.php {true, "", "sehe@", "192.168.1.1", "/file.php", 8888} usr:[email protected]/file.php?abc=1 {true, "", "usr:pwd@", "192.168.1.1", "/file.php?abc=1", unspecified} 但是等等 - 问题是什么? 如果您必须使用旧的 Boost 版本,我们会看到 问题又回来了... 因此,让我们通过在用户信息周围重新设置 raw[] 作为提示来解决这个问题。显然我宁愿升级 Boost:auto userinfo_ = x3::raw[+~x3::char_("@/#") >> x3::char_("@")]; 在 Boost 1.76 上查看它:https://godbolt.org/z/6bc5Ycrcr 输出相同,md5 校验和: c69881691195579e3184ef6024136356 1.76 c69881691195579e3184ef6024136356 1.84

回答 1 投票 0

使用 boost::spirit 进行 URL 解析

我正在尝试使用 boost::spirit 来编写 URL 解析器。我的目标是解析输入 URL(有效或无效)并将其分解为前缀、主机和后缀,如下所示: 输入 ipv6 URL: https:...

回答 1 投票 0

Boost X3。摆脱身份 lambda 将属性传播到值

我正在将代码从 Boost Qi 迁移到 X3。我有非终结符规则表达式,正在编译为结构 ast::Expression。对于最小的复制示例,我留下了 2 个形成

回答 1 投票 0

Boost Spirit AST 递归依赖问题

** 奇怪的是,编译的时候出现了如下错误。谁能告诉我为什么。 由于还有很多错误,不知道是不是这个错误导致的。由于深度递归,...

回答 1 投票 0

如何执行气灵规则来尝试OR条件下的所有规则?

我正在尝试解析这个命令模板,它可以采用以下内容: SendCmd SomeCommand Left_Side = "某些值"; SendCmd AnotherCmd "Some Literal" = Some_Value; SendCmd Anot...

回答 1 投票 0

将 BOOST Spirit X3 与自定义词法分析器结合使用

X3 解析器如何使用已经生成的标记向量。 如何定义规则,例如 枚举类标记 { aa, bb, cc}; 自动规则 = token::aa >> token::bb &...

回答 1 投票 0

如何使用 boost::spirit 解析可能丢失的无符号整数?

我需要将两个由空格分隔的无符号整数解析为两个std::可选值。其中一个或两个都可以是nan。例如,有效输入:“123 456”或“123 nan”或“nan...

回答 1 投票 0

是否可以使用 boost::spirit QI 强制执行函数参数类型

我正在编写解析器来解析内置函数列表。例如: 函数1(整数p1,字符串p2) 函数2(字符串p1,整数p2,字符串p3) 函数3(字符串p1,字符串p2,整数p3,整数p4,stri...

回答 1 投票 0

Boost spirit 样本解析代码在使用 -O3 优化标志时崩溃 - 但没有它也能工作

示例代码有一个非常小的规则来解析一个字符串——竖线('|')分隔的字符串。字符串不能包含字符('|'、'!'、'('、')'、'*')。 当我编译程序( ex.cpp )时没有...

回答 0 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.