x3 изменить парсер во время выполнения - PullRequest
0 голосов
/ 08 мая 2019

Интересно, можно ли изменить синтаксический анализатор во время выполнения, если он не изменяет составной атрибут.

Допустим, я хочу иметь возможность изменять во время выполнения символ моего синтаксического анализатора, который обнаруживает,должны присоединиться к линии от ; до ~.Оба являются просто символами, и поскольку типы c ++ и экземпляры шаблонов не меняются (в обоих случаях речь идет о char), я думаю, что должен быть какой-то путь, но я его не нахожу.Так возможно ли это?

Моя конкретная ситуация заключается в том, что я вызываю синтаксический анализатор X3 через C ++ / CLI, и мне необходимо, чтобы символ был настраиваемым из .NET.Я надеюсь, что следующего примера достаточно, чтобы понять мою проблему.

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

С уважением

1 Ответ

1 голос
/ 14 мая 2019

Вы не можете изменить синтаксический анализатор во время выполнения (за исключением трюка DSO, который я описал под вашим другим вопросом https://stackoverflow.com/a/56135824/3621421),, но вы можете сделать свой анализатор контекстно-зависимым с помощью семантических действий и / или анализаторов с сохранением состояния (например, 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";
}
...