codingdave
codingdave

Reputation: 1277

x3 modify parser at runtime

I wonder if it is possible to change the parser at runtime given it does not change the compound attribute.

Lets say I want to be able to modify at runtime the character of my parser that detects whether I have to join a line from ; to ~. Both are just characters and since the c++ types and the template instantiations dont vary (in both cases we are talking about a char) I think there must be some way, but I dont find it. So is this possible?

My concrete situation is that I am calling the X3 parser via C++/CLI and have the need that the character shall be adjustable from .NET. I hope the following example is enough to be able to understand my problem.

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

Kind regards

Upvotes: 0

Views: 107

Answers (1)

Nikita Kniazev
Nikita Kniazev

Reputation: 3785

You cannot change the parser at runtime (except a DSO trick I described under your other question https://stackoverflow.com/a/56135824/3621421), but you can make your parser context-sensitive via semantic actions and/or stateful parsers (like x3::symbols).

The state for semantic actions (or probably for your custom parser) can also be stored in a parser context. However, usually I see that folks use global or function local variables for this purpose.

A simple example:

#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";
}

Upvotes: 1

Related Questions