C++ Boost::Spirit::Qi-将规则拆分为单独的类

C++ Boost::Spirit::Qi-将规则拆分为单独的类,c++,parsing,boost,grammar,boost-spirit-qi,C++,Parsing,Boost,Grammar,Boost Spirit Qi,我想把我的规则(产品)分成不同的类。我在Boost::Spirit::Qi中找不到任何这样做的例子 Boost示例都显示了一个语法类中的规则 这是我的语法: <start> ::= @ ( <event_bool_no_param> ) <event_bool_no_param> ::= RAMPING_COMPLETED | STATE_TIMEOUT 以下是发生异常的代码位置,function_template.hpp#761: 因此,我的问题是:

我想把我的规则(产品)分成不同的类。我在Boost::Spirit::Qi中找不到任何这样做的例子

Boost示例都显示了一个语法类中的规则

这是我的语法:

<start> ::= @ ( <event_bool_no_param> )
<event_bool_no_param> ::= RAMPING_COMPLETED | STATE_TIMEOUT  
以下是发生异常的代码位置,function_template.hpp#761:

因此,我的问题是:

  • 所有规则都必须在一个语法类中吗
  • 如何在规则中引用语法类
  • 我在上面的课上犯了什么错误
  • 我正在使用:

    • Boost 1.57.0
    • VisualStudio2010
    • 视窗7

      • 这里有两个问题对我来说并不明显:

        • 语法变量
        • 使用“| |”而不是“|”
        语法实例 规则可以使用其他语法,但需要有其他语法的实例

        Event\u Grammar
        类现在看起来像:

            #include "event_bool_no_param.hpp"
        
            template <typename Iterator, typename Skipper>
            struct Event_Grammar
                : boost::spirit::qi::grammar<Iterator, Skipper>
            {
                Event_Grammar() : Event_Grammar::base_type(start)
                    {
                        using boost::spirit::ascii::char_;
                        using boost::spirit::qi::eps;
                        using qi::lit;
        
        // Notice the identifier "grammar_bool_no_param"
        // which is an instance of the grammer / rule Event_Bool_No_Param.
                        start = 
                            (
                                char_('@') >> char_('(') >> grammar_bool_no_param >> char_(')')
                            )
                            ;
        
                    }
        
                // *** A rule or grammar needs an instance!
                Event_Bool_No_Param<Iterator>               grammar_bool_no_param;
                boost::spirit::qi::rule<Iterator, Skipper>  start;
            };
        

        这里有两个问题对我来说并不明显:

        • 语法变量
        • 使用“| |”而不是“|”
        语法实例 规则可以使用其他语法,但需要有其他语法的实例

        Event\u Grammar
        类现在看起来像:

            #include "event_bool_no_param.hpp"
        
            template <typename Iterator, typename Skipper>
            struct Event_Grammar
                : boost::spirit::qi::grammar<Iterator, Skipper>
            {
                Event_Grammar() : Event_Grammar::base_type(start)
                    {
                        using boost::spirit::ascii::char_;
                        using boost::spirit::qi::eps;
                        using qi::lit;
        
        // Notice the identifier "grammar_bool_no_param"
        // which is an instance of the grammer / rule Event_Bool_No_Param.
                        start = 
                            (
                                char_('@') >> char_('(') >> grammar_bool_no_param >> char_(')')
                            )
                            ;
        
                    }
        
                // *** A rule or grammar needs an instance!
                Event_Bool_No_Param<Iterator>               grammar_bool_no_param;
                boost::spirit::qi::rule<Iterator, Skipper>  start;
            };
        
        首先是问题:

      • 所有规则都必须在一个语法类中吗


        绝对不是。语法只是一种将规则组合在一起并在需要时提供附加状态的机制。语法只是一个类/结构,因此它是封装语法概念的非常方便的工具

      • 如何在规则中引用语法类

        你需要一个语法实例。暂时的失败会引起悲伤

      • 我在上面的课上犯了什么错误

        错误在于,在构建规则时,您正在创建临时规则。您需要一个语法(或规则)实例,该实例将被组合成其他语法和规则

      • 例如,以下各项:

        #include <boost/spirit/home/qi.hpp>
        namespace qi    = boost::spirit::qi;
        namespace ascii = boost::spirit::qi::ascii;
        
        template <typename Iterator>
        struct Event_Bool_No_Param : qi::grammar<Iterator>
        {
            Event_Bool_No_Param () 
                : Event_Bool_No_Param::base_type(start)
            {
                using qi::lit;
        
                start =
                    lit("STATE_TIMEOUT") | lit("RAMPING_COMPLETED") | lit("PASSIVE_MEAS_COMPLETED")
                    ;
            }
            qi::rule<Iterator> start;
        };
        
        
        template <typename Iterator, typename Skipper>
        struct Event_Grammar : boost::spirit::qi::grammar<Iterator, Skipper>
        {
            Event_Grammar() : Event_Grammar::base_type(start)
            {
                using boost::spirit::ascii::char_;
        
                start = 
                    char_('@') >> char_('(') >> event_no_param >> char_(')')
                    ;
        
            }
            qi::rule<Iterator, Skipper> start;
            Event_Bool_No_Param<Iterator> event_no_param;
        };
        
        int main()
        {
            using iterator_t = std::string::const_iterator;
            std::string input = "@ ( STATE_TIMEOUT )";
            iterator_t iter = input.begin();
            iterator_t end = input.end();
        
            Event_Grammar<iterator_t,ascii::space_type> grammar;   
        
            bool ok = qi::phrase_parse( iter, end
                    , grammar
                    , ascii::space
                    );
        
            return ok? 0 : 255;
        }
        
        首先是问题:

      • 所有规则都必须在一个语法类中吗


        绝对不是。语法只是一种将规则组合在一起并在需要时提供附加状态的机制。语法只是一个类/结构,因此它是封装语法概念的非常方便的工具

      • 如何在规则中引用语法类

        你需要一个语法实例。暂时的失败会引起悲伤

      • 我在上面的课上犯了什么错误

        错误在于,在构建规则时,您正在创建临时规则。您需要一个语法(或规则)实例,该实例将被组合成其他语法和规则

      • 例如,以下各项:

        #include <boost/spirit/home/qi.hpp>
        namespace qi    = boost::spirit::qi;
        namespace ascii = boost::spirit::qi::ascii;
        
        template <typename Iterator>
        struct Event_Bool_No_Param : qi::grammar<Iterator>
        {
            Event_Bool_No_Param () 
                : Event_Bool_No_Param::base_type(start)
            {
                using qi::lit;
        
                start =
                    lit("STATE_TIMEOUT") | lit("RAMPING_COMPLETED") | lit("PASSIVE_MEAS_COMPLETED")
                    ;
            }
            qi::rule<Iterator> start;
        };
        
        
        template <typename Iterator, typename Skipper>
        struct Event_Grammar : boost::spirit::qi::grammar<Iterator, Skipper>
        {
            Event_Grammar() : Event_Grammar::base_type(start)
            {
                using boost::spirit::ascii::char_;
        
                start = 
                    char_('@') >> char_('(') >> event_no_param >> char_(')')
                    ;
        
            }
            qi::rule<Iterator, Skipper> start;
            Event_Bool_No_Param<Iterator> event_no_param;
        };
        
        int main()
        {
            using iterator_t = std::string::const_iterator;
            std::string input = "@ ( STATE_TIMEOUT )";
            iterator_t iter = input.begin();
            iterator_t end = input.end();
        
            Event_Grammar<iterator_t,ascii::space_type> grammar;   
        
            bool ok = qi::phrase_parse( iter, end
                    , grammar
                    , ascii::space
                    );
        
            return ok? 0 : 255;
        }
        

        完全可以猜测(我没有使用这个版本的boost spirit),您的
        事件\u Bool\u No\u参数的生命周期是否需要持续?看看是否有一个(智能)指针指向存储在
        Event\u Grammar
        中的那个子程序,看看你的问题是否消失了?@Yakk:谢谢你关于变量的提示。作为完全的猜测(我没有使用这个版本的boost spirit),也许你的
        Event\u Bool\u No\u参数的生命周期需要持续下去?查看是否在
        事件\语法
        中存储了指向该子语法的(智能)指针,并查看您的问题是否消失?@Yakk:感谢您提供有关变量的提示。“语法只是一种将规则组合在一起并在需要时提供附加状态的机制。”。我一直将
        语法
        视为对同一类型参数(例如
        迭代器
        跳过器
        )上的一组规则进行参数化的一种方法。如果你不需要泛型,你可以保留“自由”的规则变量。“语法只是一种将规则组合在一起并在需要时提供额外状态的机制。”。我一直将
        语法
        视为对同一类型参数(例如
        迭代器
        跳过器
        )上的一组规则进行参数化的一种方法。如果不需要泛型,可以保留“自由”规则变量。
            #include "event_bool_no_param.hpp"
        
            template <typename Iterator, typename Skipper>
            struct Event_Grammar
                : boost::spirit::qi::grammar<Iterator, Skipper>
            {
                Event_Grammar() : Event_Grammar::base_type(start)
                    {
                        using boost::spirit::ascii::char_;
                        using boost::spirit::qi::eps;
                        using qi::lit;
        
        // Notice the identifier "grammar_bool_no_param"
        // which is an instance of the grammer / rule Event_Bool_No_Param.
                        start = 
                            (
                                char_('@') >> char_('(') >> grammar_bool_no_param >> char_(')')
                            )
                            ;
        
                    }
        
                // *** A rule or grammar needs an instance!
                Event_Bool_No_Param<Iterator>               grammar_bool_no_param;
                boost::spirit::qi::rule<Iterator, Skipper>  start;
            };
        
        template <typename Iterator>
        struct Event_Bool_No_Param
            : qi::grammar<Iterator>
        {
            Event_Bool_No_Param () 
                : Event_Bool_No_Param::base_type(start)
                {
                    using qi::lexeme;
                    using qi::lit;
        
                    start =
                        lit("STATE_TIMEOUT") || lit("RAMPING_COMPLETED") || lit("PASSIVE_MEAS_COMPLETED")
                        ;
                }
            qi::rule<Iterator> start;
        };
        
        #include <boost/spirit/home/qi.hpp>
        namespace qi    = boost::spirit::qi;
        namespace ascii = boost::spirit::qi::ascii;
        
        template <typename Iterator>
        struct Event_Bool_No_Param : qi::grammar<Iterator>
        {
            Event_Bool_No_Param () 
                : Event_Bool_No_Param::base_type(start)
            {
                using qi::lit;
        
                start =
                    lit("STATE_TIMEOUT") | lit("RAMPING_COMPLETED") | lit("PASSIVE_MEAS_COMPLETED")
                    ;
            }
            qi::rule<Iterator> start;
        };
        
        
        template <typename Iterator, typename Skipper>
        struct Event_Grammar : boost::spirit::qi::grammar<Iterator, Skipper>
        {
            Event_Grammar() : Event_Grammar::base_type(start)
            {
                using boost::spirit::ascii::char_;
        
                start = 
                    char_('@') >> char_('(') >> event_no_param >> char_(')')
                    ;
        
            }
            qi::rule<Iterator, Skipper> start;
            Event_Bool_No_Param<Iterator> event_no_param;
        };
        
        int main()
        {
            using iterator_t = std::string::const_iterator;
            std::string input = "@ ( STATE_TIMEOUT )";
            iterator_t iter = input.begin();
            iterator_t end = input.end();
        
            Event_Grammar<iterator_t,ascii::space_type> grammar;   
        
            bool ok = qi::phrase_parse( iter, end
                    , grammar
                    , ascii::space
                    );
        
            return ok? 0 : 255;
        }
        
            A >> -B | B