x3在运行时修改解析器

时间:2019-05-08 16:36:17

标签: c++ parsing boost boost-spirit-x3

我想知道是否可以在运行时更改解析器,因为它不会更改复合属性。

让我们说我希望能够在运行时修改解析器的字符,该字符检测我是否必须加入从;~的行。两者都只是字符,并且由于c ++类型和模板实例化没有变化(在两种情况下,我们都在谈论char),我认为必须有某种方法,但我找不到。那有可能吗?

我的具体情况是我正在通过C ++ / CLI调用X3解析器,并且需要从.NET调整字符。我希望以下示例足以理解我的问题。

http://coliru.stacked-crooked.com/a/1cc2f2836dbfaa46

亲切的问候

1 个答案:

答案 0 :(得分:1)

您不能在运行时更改解析器(除了我在另一个问题https://stackoverflow.com/a/56135824/3621421下描述的DSO技巧),但是可以通过语义动作和/或使解析器上下文敏感有状态的解析器(例如x3::symbols)。

语义动作(或可能是您的自定义解析器)的状态也可以存储在解析器上下文中。 但是,通常我会看到人们为此目的使用全局或局部函数。

一个简单的例子:

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

namespace x3 = boost::spirit::x3;

int main()
{
    char const* s = "sep=,\n1,2,3", * e = s + std::strlen(s);
    auto p = "sep=" >> x3::with<struct sep_tag, char>('\0')[
         x3::char_[([](auto& ctx) { x3::get<struct sep_tag>(ctx) = _attr(ctx); })] >> x3::eol
      >> x3::int_ % x3::char_[([](auto& ctx) { _pass(ctx) = x3::get<struct sep_tag>(ctx) == _attr(ctx); })]
    ];
    if (parse(s, e, p) && s == e)
        std::cout << "OK\n";
    else
        std::cout << "Failed\n";
}