问题标签 [boost-spirit-x3]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
311 浏览

c++ - Spirit x3 无法传播可选类型的属性

一个简单的解析器,如Coliru上的。解析器-(+x3::alpha)应该能够boost::optional<std::string>像 Qi 那样传播类型的属性。但它不编译。

0 投票
1 回答
143 浏览

c++ - 如何在 x3 中用 qi::_1/qi::_N 重写 qi 解析器?

假设我们要解析一个内积表达式并得到结果。

qi::_1并且qi::_2非常方便在解析器中引用第i个属性。

在精神 x3 中,没有这样的 qi::_1 ... qi::_N。我应该使用一对向量作为属性吗?解析这种内积的推荐方法是什么?

0 投票
1 回答
279 浏览

c++ - 如何在 x3 中重写具有继承属性的 qi 解析器?

如果继承的属性用于语义动作,我们可以使用x3::with指令。

如果我们想将属性用作解析器的一部分怎么办?例如,一个简单的解析器匹配 1 个或多个字母字符,但该字符来自参数字符集。

或者参数字符集可以用作惰性解析器。

x3::with 指令将此本地值放在上下文中。我不确定我们是否可以在语义操作之外使用此上下文并最终生成解析器。

0 投票
1 回答
471 浏览

c++ - 精神x3:本地定义的规则定义必须附加一个属性?

简单的 x3 代码无法编译,因为第二个 ruleTest 或整个解析器没有附加任何内容。即使我们放x3::omit[ruleTest]第二个ruleTest,它仍然无法编译。

只有当我们将 lambda 或属性附加到 x3::parse 或使用 BOOST_SPIRIT_DEFINE 全局定义 ruleTest 时才能解决问题。

0 投票
1 回答
226 浏览

c++ - boost.spirit x3 move_to 并列出 ast 成员

我实现的 BNF 有一个有趣的规则,根据操作员的不同,这些术语可以被链接或事件不在这个生产规则中。因此我使用相同的 AST 数据结构,因为只有枚举发生了变化:

这就是想法 - 运算符 X,Y,Z 仅将一个块添加到列表中。在编译器错误之后,我必须专门化 x3::traits::move_to,但我没有找到任何解决方案来编译它。有什么办法吗?list::emplace() 和 std::move() 在这里安全吗?

0 投票
0 回答
158 浏览

c++ - 优化语法

也在 boost Spirit 邮件列表 http://boost.2283326.n4.nabble.com/Spirit-X3-Boost-1-59-Compilation-never-finishes-for-a-recursive-grammar-td4693813 上提出了问题。 html

我正在根据 RFC 创建一个 xpath2.0 解析器。它基本上是我正在从事的另一个项目的子项目。

在取得了一些初步的成功之后,我犯了一个错误,即编写了一堆语法规则和 AST,而不是在每个点都编译和测试它。在那之后,我基本上有一本小说要阅读的模板错误消息(实际上是我的错)。

下面我介绍了 xpath 的简化语法(不是特别按照 RFC),它没有完成编译,或者当我的 mac 在大约 7 分钟后开始变慢时我不得不停止这个过程。

编译为

编译器:Clang 3.8

增强版:1.59

基于较低模板深度的模板错误实例化,我很确定某处深度递归正在进行。无论如何要优化上述语法以免引起这个问题?

谢谢。

0 投票
1 回答
631 浏览

c++ - 带有调试输出的 X3 解析器段错误 (BOOST_SPIRIT_X3_DEBUG)

更新

这个问题涉及两个问题(如接受的答案所示),这两个问题都存在于 Boost 1.64 附带的 Boost Spirit X3 版本中,但现在都已修复(或至少在编译时检测到)在撰写本文时(2017-04-30)开发分支。

我已经更新了mcve 项目以反映我使用开发分支而不是最新的 boost 版本所做的更改,希望它可以帮助其他面临类似问题的人。


原来的问题

我正在尝试学习如何将 Spirit X3 解析器分解为单独的可重用语法,正如示例代码(尤其是 rexpr_full 和 calc)以及CppCon 2015BoostCon的演示文稿所鼓励的那样。

我有一个符号表(基本上将不同类型映射到我支持的类型的枚举类),我想在多个解析器中重用它。我能找到的符号表的唯一示例是罗马数字示例,它位于单个源文件中。

当我尝试以更结构化示例的样式将符号表移动到其自己的 cpp/h 文件中时,如果我尝试解析不在符号表中的任何字符串,我的解析器将出现段错误。如果符号表是在与使用它的解析器相同的编译单元中定义的,则会引发预期异常(这是我期望它做的)。

定义 BOOST_SPIRIT_X3_DEBUG 后,我得到以下输出:

我做了一个小项目,展示了我想要实现的目标,可以在这里找到:https ://github.com/sigbjornlo/spirit_fruit_mcve

我的问题:

  • 为什么在这种情况下将符号解析器移动到单独的编译单元会导致分段错误?
  • 使符号表可在多个解析器中重用的推荐方法是什么?(在 MCVE 中,我显然只fruit在另一个解析器中使用解析器,但在我的完整项目中,我想在其他几个解析器中使用它。)

以下是 MCVE 项目的代码:

主文件

常见的.h

水果.h

水果.cpp

0 投票
1 回答
256 浏览

c++ - 带有单独 TU 的 x3 链接器错误

随着解析器的增长,我将一些规则分成不同的翻译单元(TU),链接器问题也随之增加。经过数周的尝试和错误都没有成功,我将我的约 50 条规则减少到(希望)这里展示的最小示例。我在使用 boost spirit x3 的单独解析器时阅读了相关的链接错误并进行了检查,我在上下文 typedef 中使用iso8859_1::space_type并稍后调用iso8859_1::space。另外我不让编译器推断 iterator_type。

通过替换一些东西,我更喜欢链接器错误:

我对__gnu_cxx17迭代器很恼火(来自 libstdc++??)。我确实尝试了 g++7.1.0,结果相同。

附加文件以使用 CMake 文件重现链接器错误(使用选项 LINKER_ERROR 获取或什至不获取(没有 TU 的单体构建))。

ast.hpp

语法定义.hpp

文字定义.hpp

文字.cpp

字面量.hpp

主文件

parser_config.hpp

最后是CMakeLists.txt

该代码也在wandbox

将 parser_api::string_literal() 设置到实例文件 literal.cpp 也不会改变结果(如预期的那样)。希望这不是我的愚蠢错误,但几周后我终于...

附录

我还测试了 Joel de Guzman 的提示以插入int x = context_type{};到 literal.cpp 和 main.cpp 以获取使用的上下文 - 它都相同:

0 投票
1 回答
269 浏览

c++ - 递归 x3 解析器,结果传递

(1) 假设我们要解析一个由 包围的简单递归块{}

这个递归解析器非常简单。

(2) 然后块变得更复杂。也可以被包围[]

我们需要在某个地方存储我们有什么样的左括号。由于 x3 没有局部变量,我们可以使用属性 ( x3::_val) 代替。

(3) 块内容(被包围的部分),我们称之为参数,可能比这个例子复杂得多。所以我们决定为它创建一个规则。此属性解决方案在这种情况下不起作用。幸运的是,我们仍然有x3::with指令。我们可以将左括号(或期望的右括号)保存在堆栈引用中,并将其传递到下一层。

代码在Coliru上。

问题:这就是我们为这类问题编写递归 x3 解析器的方式吗?有了灵气的本地属性和继承属性,解决起来似乎就简单多了。谢谢。

0 投票
1 回答
479 浏览

c++ - 如何使用 Boost Spirit x3 编写具有两个后操作数语法的二元运算符?

我正在关注这个例子:https ://github.com/boostorg/spirit/blob/develop/example/x3/calc/calc9/expression_def.hpp

我想要完成的是编写一个像 min{x}{y} 这样解析和生成的规则。大多数代码都使用像 x + y 这样的表达式语法,但现在我想将两个操作数放置并解析为运算符的 rhs。

我在 expression_def.hpp 文件中添加了以下代码:

这工作正常。但它只能解析像 {x} min {y} 这样的东西。我希望能够解析 min {x} {y}。我尝试了许多组合,例如:

binarypost_op >> ('{' > unary_expr > '}') > ('{' > unary_expr > '}') 等等。但我似乎无法弄清楚写这个的正确方法是什么?有什么建议/意见吗?