taocpp / PEGTL

Parsing Expression Grammar Template Library
Boost Software License 1.0
1.94k stars 229 forks source link

Issues with change_action_and_state #359

Closed chs-1980 closed 8 months ago

chs-1980 commented 8 months ago

Hi,

This is probably a dumb question and i am just missing something obvious but whatever i do i can't get change_action_and_state (or change_state for that matter) to work. Interestingly enough change_action standalone works as expected.

#ifndef ACTION_H
#define ACTION_H

namespace ModelScript {

    namespace Actions {

        struct DefinitionState
        {
            ModelScript::Entry entry;
            size_t index;
            ModelScript::LLVMHelper* helper;
            AddSymTableEntry addSymTableEntryFunc;

            DefinitionState()
                : entry()
                , index(0)
                , helper(nullptr)
                , addSymTableEntryFunc(nullptr)
            {

            }

        };

        struct StatementState
        {
            std::vector<ModelScript::ExprAST*> nodes = {};

            //StatementState()
            //    : nodes(std::vector<ModelScript::ExprAST*>())
            //{

            //}

            template<typename ParseInput>
            explicit StatementState(const ParseInput& /*unused*/, ModelScript::Actions::DefinitionState& c)
            {

            }

            template<typename ParseInput>
            void success(const ParseInput& /*unused*/, ModelScript::Actions::DefinitionState& c)
            {
            }

        };

        // Primary action class template.
        template<typename Rule>
        struct ms_stmt_action : tao::pegtl::nothing<Rule> {};

        template<>
        struct ms_stmt_action<grammar::rule_bool>
        {
            // Implement an apply() function that will be called by
            // the PEGTL every time tao::pegtl::any matches during
            // the parsing run.
            template<typename ActionInput>
            static void apply(const ActionInput& in, StatementState& state)
            {
                // Get the portion of the original input that the
                // rule matched this time as string and append it
                // to the result string.
                std::string val = in.string();
                /*std::transform(val.begin(), val.end(), val.begin(), ::toupper);
                entry.initvalue = val == "TRUE";*/
            }
        };

        // Primary action class template.
        template<typename Rule>
        struct ms_def_action : tao::pegtl::nothing<Rule> {};

        template<>
        struct ms_def_action<grammar::rule_statement_block>
            : tao::pegtl::change_action_and_state<ms_stmt_action, ModelScript::Actions::StatementState> //TODO replace with change_action_and_state(s)
        {

        };

 ...

    }

}

#endif

The problem is that no matter what i do i get the static_assert that the new state cannot be instantiated, but as you can see StatementState has the necessary constructor in my opinion. The interesting thing is that i've rewritten the unit-test for change_action_and_state to look exactly like this (meaning i have two state-structs instead of an int- and a struct-state) and this works like a charm but no matter what i do, my code refuses to compile. If i implement the parameterless constructor the instantiation check succeeds but afterwards it complains that the success-function can't be found. Does anyone have an idea what i am missing here?

chs-1980 commented 8 months ago

I'm closing the issue as actions weren't the right tool for what i wanted to achieve so i went with traversing the AST and this works like a charm