标签: boost-spirit-x3

Boost.x3:属性在备选方案之间累积

我有一个用于解析标识符的解析器foo, bar, baz和一个用于解析嵌套标识符的解析器,foo::bar, foo::bar.baz, foo::bar.baz.baham 它们都解析为相同的ast结构,如下所示:

struct identifier : x3::position_tagged{
    std::vector <std::string> namespaces;
    std::vector <std::string> classes;
    std::string identifier;

};
Run Code Online (Sandbox Code Playgroud)

解析器identifier看起来像这样:

#define VEC_ATR x3::attr(std::vector<std::string>({})) //ugly hack

auto const identifier_def =
                VEC_ATR
                >> VEC_ATR
                >> id_string;
Run Code Online (Sandbox Code Playgroud)

对于nested_identifier这样的:

auto const nested_identifier_def =
        x3::lexeme[
                (+(id_string >> "::") >> +(id_string >> ".") > id_string)
                | (+(id_string >> "::") >> VEC_ATR > id_string)
                | (VEC_ATR >> +(id_string >> ".") > id_string)
                | identifier

        ];
Run Code Online (Sandbox Code Playgroud)

我知道这个宏让我感到羞耻.标识符解析器工作正常,但 nested_identifier有一个奇怪的行为,如果我尝试解析像foo::bar::baz落在了解析器的AST对象,拥有所有的命名空间,在这种情况下 …

c++ parsing boost-spirit boost-spirit-x3

3
推荐指数
1
解决办法
456
查看次数

阻止 X3 符号匹配子字符串

如何防止 X3 符号解析器匹配部分标记?在下面的示例中,我想匹配“foo”,但不匹配“foobar”。我尝试将符号解析器放入指令中,lexeme就像处理标识符一样,但没有任何匹配。

感谢您的任何见解!

#include <string>
#include <iostream>
#include <iomanip>

#include <boost/spirit/home/x3.hpp>


int main() {

  boost::spirit::x3::symbols<int> sym;
  sym.add("foo", 1);

  for (std::string const input : {
      "foo",
      "foobar",
      "barfoo"
        })
    {
      using namespace boost::spirit::x3;

      std::cout << "\nParsing " << std::left << std::setw(20) << ("'" + input + "':");

      int v;
      auto iter = input.begin();
      auto end  = input.end();
      bool ok;
      {
        // what's right rule??

        // this matches nothing
        // auto r = lexeme[sym - alnum];

        // this matchs …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit c++11 boost-spirit-x3

2
推荐指数
1
解决办法
633
查看次数

boost :: spirit :: x3属性兼容性规则,直觉还是代码?

是否有某个文档描述了各种spirit :: x3规则定义操作如何影响属性兼容性?

我很惊讶:

x3::lexeme[ x3::alpha > *(x3::alnum | x3::char_('_')) ]
Run Code Online (Sandbox Code Playgroud)

无法移动到融合适应的结构中:

struct Name {
    std::string value;
};
Run Code Online (Sandbox Code Playgroud)

目前,我摆脱了第一个强制字母字符,但我仍然想表达一个规则,该规则定义名称字符串必须以字母开头.这是其中一种情况,我需要尝试添加eps,直到它工作,或有一个明确的原因,为什么上述不起作用?

如果在某处写下来,我道歉,我找不到它.

c++ boost boost-spirit boost-spirit-x3

2
推荐指数
1
解决办法
445
查看次数

使用boost精神x3解析为具有布尔或枚举成员的结构

如果我有一个结构:

struct person{
    bool is_male;
    std::string name;
    std::vector<std::string> friends;
}
Run Code Online (Sandbox Code Playgroud)

要么

enum class gender_t{male, female}
struct person{
        gender_t gender;
        std::string name;
        std::vector<std::string> friends;
}
Run Code Online (Sandbox Code Playgroud)

如何使用boost.spirit X3解析此结构?规则如何解析“ alice male bob”之类的字符串,解析器将返回一个名称为alice的对象,该对象是male,并且有一个朋友bob。如果这个人不是女性,那么如果性别只是露骨的话,会是什么样?

c++ parsing boost-spirit c++14 boost-spirit-x3

2
推荐指数
1
解决办法
384
查看次数

递归x3解析器,结果传递

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

{
    Some text.
    {
        {
            Some more text.
        }
        Some Text again.
        {}
    }
}
Run Code Online (Sandbox Code Playgroud)

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

x3::rule<struct idBlock1> const ruleBlock1{"Block1"};
auto const ruleBlock1_def =
    x3::lit('{') >>
    *(
        ruleBlock1 |
        (x3::char_ - x3::lit('}'))
    ) >>
    x3::lit('}');

BOOST_SPIRIT_DEFINE(ruleBlock1)
Run Code Online (Sandbox Code Playgroud)

(2)然后块变得更复杂.它也可能被包围[].

{
    Some text.
    [
        {
            Some more text.
        }
        Some Text again.
        []
    ]
}
Run Code Online (Sandbox Code Playgroud)

我们需要在某处存放我们拥有的开放式支架.由于x3没有本地,我们可能会使用attribute(x3::_val).

x3::rule<struct idBlock2, char> const ruleBlock2{"Block2"};
auto const ruleBlock2_def = x3::rule<struct _, char>{} =
    (
        x3::lit('{')[([](auto& ctx){x3::_val(ctx)='}';})] |
        x3::lit('[')[([](auto& ctx){x3::_val(ctx)=']';})]
    ) …
Run Code Online (Sandbox Code Playgroud)

c++ recursion boost boost-spirit boost-spirit-x3

2
推荐指数
1
解决办法
163
查看次数

X3 解析规则无法编译

我正在通过编写一个解析器来解析 NAMS 使用的两种十六进制数变体来学习 Boost Spirit:

  1. 用的任一后缀十六进制数0x/0h或前缀h/ x
  2. 前缀为$and 的十六进制数字后必须跟一个十进制数字。

这是我到目前为止和Coliru Session 提出的内容

//#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/spirit/include/support_extended_variant.hpp>

namespace x3 = boost::spirit::x3;

namespace ast {
    struct hex_data : std::string {};
    struct pascal_hex_data : std::string {};

    struct declared_data : boost::spirit::extended_variant<hex_data, pascal_hex_data>
    {
        declared_data () : base_type ()                              { std::cout << "ctor default\n";               } 
        declared_data (hex_data const& rhs) : base_type (rhs)        { std::cout << "ctor …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit boost-spirit-x3

2
推荐指数
1
解决办法
339
查看次数

Spirit X3,这种错误处理方法有用吗?

在阅读了 Spirit X3 关于错误处理的教程和一些实验之后。我得出了一个结论。

\n\n

我相信 X3 中的错误处理主题还有一些改进的空间。从我的角度来看,一个重要的目标是提供有意义的错误消息。首先也是最重要的是添加一个将_pass(ctx)成员设置为 false 的语义操作,\xe2\x80\x99 不会这样做,因为 X3 会尝试匹配其他内容。仅抛出 anx3::expectation_failure会提前退出解析函数,即不尝试匹配其他任何内容。所以剩下的就是解析器指令expect[a]和解析器operator>以及手动抛出x3::expectation_failure从语义操作中手动抛出。我确实相信有关此错误处理的词汇量太有限。请考虑以下 X3 PEG 语法行:

\n\n
const auto a = a1 >> a2 >> a3;\nconst auto b = b1 >> b2 >> b3;\nconst auto c = c1 >> c2 >> c3;\n\nconst auto main_rule__def =\n(\n a |\n b |\n c );\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在对于表达式a我不能使用expect[]or operator>,因为其他替代方案可能是有效的。我可能是错的,但我认为 X3 要求我拼写出可以匹配的备用错误表达式,如果它们匹配,它们可以抛出x3::expectation_failure这很麻烦。

\n\n

问题是,是否有一种好方法可以使用当前的 X3 设施通过 …

c++ boost-spirit boost-spirit-x3

2
推荐指数
1
解决办法
858
查看次数

How do you get a string out of a Boost Spirit X3 lexeme parser?

What is the simplest way to make a semantic action that extracts a string from a typical identifier parser based on boost::spirit::x3::lexeme?

I thought it might be possible to bypass needing to unpack the attribute and just use iterators into the input stream but apparently x3::_where does not do what I think it does.

The following yields output being empty. I expected it to contain "foobar_hello".

namespace x3 = boost::spirit::x3;

using x3::_where;
using x3::lexeme;
using x3::alpha;

auto ctx_to_string = …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit boost-spirit-x3

2
推荐指数
1
解决办法
338
查看次数

我什么时候可以使用期望运算符?

我正在使用boost spirit x3进行解析.我完成了语法,解析器按预期解析.现在我想添加错误处理,所以我必须为我的语法添加期望点.我的问题是我何时可以使用期望运算符>而不是"跟随"运算符>>?我只能用它像a > b如果a >> b在语法的另一部分永远不会发生?

c++ parsing boost-spirit c++14 boost-spirit-x3

1
推荐指数
1
解决办法
152
查看次数

Spirit V2和X3的状态

Spirit X3如此“无状态”的目的是什么?

Spirit V2中“状态”的不良方面

回顾Spirit V2,“语法”在许多方面在概念上都是有状态的。这是因为语法是类实例。

基本上,使语法(甚至任何一条规则)变得有状态有很多不良方面:

  • 它可能会使您的语法不可重入;
  • 它可能会给您的语法实例增加线程安全性;
  • 自我管理的“标志”是一场灾难。

从理论上讲,添加外部状态会使您的语法变得不平凡。

真的不需要状态吗?

相反,您可以说任何解析器都是有状态的(因为它解析当前上下文并且上下文是状态)。下面是程序员添加其他“上下文”的一个好例子:

quoted_string_ = as_string [omit [char_("'\"") [_a = _1]] >> *(char_ - lit(_a)) >> lit(_a)]
Run Code Online (Sandbox Code Playgroud)

qi::locals是非外部国家的好兆头。

程序员可以在语法中添加一些“外部状态”,并且在大多数情况下,它们只是在做错误的事情:

func_call_ = func_name_ >> lit('(') >> eps [ref(is_inside_function_call) = true] >> ...
Run Code Online (Sandbox Code Playgroud)

但是,在某些极端情况下,外部状态很有用。

macro_type_1_ =
    lit("{{{") [PUSH_STATE(macro_ctx, Macro::Type1)] >> (
        ((any_expr_ - end_of_macro_ctx_) >> lit("}}}") >> eps [POP_STATE(macro_ctx)]) |
        (eps [POP_STATE(macro_ctx)] >> eps [_pass = false])
    )
;
macro_type_2_ =
    lit("[[[") [PUSH_STATE(macro_ctx, Macro::Type2)] >> (
        ((any_expr_ - end_of_macro_ctx_) >> …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-spirit-qi boost-spirit-x3

0
推荐指数
1
解决办法
477
查看次数