Обрабатывать правильное состояние с помощью грамматики pegtl

Я очень плохо знаком с peg и pegtl, так что, вероятно, я что-то упустил.
У меня есть грамматика, очень похожая на следующую:

using namespace tao::pegtl;

struct A : one<'A'> { };
struct B : one<'B'> { };

struct comp : seq<plus<sor<seq<A, B>, A>>,eof> { };

template< typename Rule >
struct test_action : nothing< Rule > {};

template<>
struct test_action<A>
{
template< typename Input >
static void apply(const Input& in)
{
std::cout << "A";
}
};

template<>
struct test_action<B>
{
template< typename Input >
static void apply(const Input& in)
{
std::cout << "B";
}
};

void test()
{
parse< comp, test_action >(memory_input("AAB", ""));
}

Разбор работает отлично, но слишком много активаций test_action :: apply.
Программа выводит «AAAB», потому что, если я хорошо понимаю, анализ разбирает первый вариант (AB) для первого символа и завершается неудачей, затем продолжается
с другой (А). Но даже если он «перематывает», он всегда вызывает test_action :: apply.
Как правильно справиться с этой ситуацией?
Мое намерение состоит в том, чтобы вывести «AAB», возможно, без осложнений грамматики.

1

Решение

Я попросил авторов библиотеки pegtl любезно дать мне правильный путь: лучше всего сделать так, чтобы ваш синтаксический анализатор создал дерево синтаксического анализа, которое легко исправить, когда он возвращается с помощью простых операций push и pop.

Я разработал код ниже для тех, у кого были подобные сомнения.

  • избегайте возврата в правилах с прикрепленными действиями:

    namespace solution_a {

    using namespace tao::pegtl;
    
    struct A : one<'A'> { };
    struct B : one<'B'> { };
    
    struct real_A : A {};
    struct real_AB : seq<A, B> {};
    
    struct comp : seq<plus<sor<real_AB, real_A>>,eof> { };
    
    template< typename Rule >
    struct test_action : nothing< Rule > {};
    
    template<>
    struct test_action<real_A>
    {
    template< typename Input >
    static void apply(const Input& in)
    {
    std::cout << "A";
    }
    };
    
    template<>
    struct test_action<real_AB>
    {
    template< typename Input >
    static void apply(const Input& in)
    {
    std::cout << "AB";
    }
    };void test()
    {
    parse< comp, test_action >(memory_input("AAB", ""));
    }
    
  • построить дерево разбора:

    namespace solution_b {

    using namespace tao::pegtl;
    
    struct A : one<'A'> { };
    struct B : one<'B'> { };struct comp : seq<plus<sor<seq<A, B>, A>>, eof> { };
    
    template< typename Rule >
    struct test_action : nothing< Rule > {};void test()
    {
    auto root = parse_tree::parse<comp>(memory_input("AAB", ""));
    }
    

    }

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]