在 Boost Spirit 2.5.2 中按层次结构拆分语法

Split grammar hierarchically in Boost Spirit 2.5.2

本文关键字:层次结构 拆分 语法 Boost Spirit      更新时间:2023-10-16

我在Classic Spirit中有以下代码:

/// _BasicRules.h
template <typename scanT> class _BasicRules {
    public:
        _BasicRules() {
            // ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
            ALPHA = range_p(0x41, 0x5A) | range_p(0x61, 0x7A);
            ...
        }
    protected:
        boost::spirit::rule<scanT> ALPHA;
        ...
};
// CommonRules.h
template <typename scanT> class _CommonRules : public _BasicRules<scanT> {...};
// _UriRules.h
template <typename scanT> class _UriRules : public _CommonRules<scanT> {...};
// _HeaderRules.h
template <class scanT> class _HeaderRules : public _UriRules<scanT> {...};
// _SipRules.h
template <typename scanT> class SipGrammar::definition : public _HeaderRules<scanT> {
public:
    definition(SipGrammar const& self) {
        SIP_message = Request | Response; 
        Request = Request_Line >> *(message_header) >> CRLF >> !message_body;
        ...
    }
    const rule<scanT> & start() const
    {
        return SIP_message;
    }
  private:
    boost::spirit::rule<scanT> SIP_message;
    using _BasicRules<scanT>::DIGIT;
    using _CommonRules<scanT>::token;
    ...
};

我只是将基于RFC3261的SIP消息解析器从Spirirt Classic转换为新的Spirit 2.5.2。我已经将整个语法拆分为多个继承文件,因为语法真的很大。

我正在编写此代码;

....
template <typename Iterator> struct _HeaderRules:grammar<Iterator>, _UriRules<Iterator> {...}
template <typename Iterator> struct SipGrammar:grammar<Iterator>, _HeaderRules<Iterator> {
    SipGrammar():SipGrammar::base_type(SIP_Message){...}
    ...
};

这行不通。您是否建议在 Spirit 2.5.2 中分层拆分语法的来源。

无论如何,继承在这里都不是一个合乎逻辑的选择(SipGrammar 在任何意义上都不能替代 HeaderRules)。

通常

的方法是聚合:

template <typename Iterator> struct SipGrammar : grammar<Iterator>
{
    SipGrammar() : SipGrammar::base_type(SIP_Message)
    {
        ...
    }
  private:
     HeaderRule<Iterator> _headerRules;
    ...
};

Boost Spirit源代码树中的编译器示例包含几个示例,说明如何在同时拆分hpp/cpp文件时执行此操作,以减少编译时间:

  • http://www.boost.org/doc/libs/1_54_0/libs/spirit/example/qi/compiler_tutorial/