5 grammar
grammar是rule集合的一个封装,用于把一些相关的rule组合到一起,组成一个文法类。
就实现上来说:grammar本身只是一个接口;我们必须定义一个子类,符合grammar的接口定义。(类似于parser)
5.1 grammar规范
要想成为一个合格的grammar,必须满足一下条件。
struct my_grammar : public grammar<my_grammar>
{
//1.定义个模板类definition,模板参数会传入ScannerT
template <typename ScannerT>
struct definition
{
rule<ScannerT> r;
//2.类definition必须有一个ctor,其参数是自定义的grammar对象。
//在构造器类,定义相关的rule对象。
definition(my_grammar const& self) { r = /*..define here..*/; }
//3.必须定义一个成员函数start(),返回一个rule<ScannerT>对象。
rule<ScannerT> const& start() const { return r; }
};
};
5.2 grammar implementation
grammar类首先是一个parser,使用的时候与普通parser没什么两样,都是调用parse函数。
grammar对parser接口的实现与rule非常相似;唯一不同的是grammar::parse_main函数。
parse_main(ScannerT const& scan) const
{ return impl::grammar_parser_parse<0>(this, scan); }
看看impl::grammar_parser_parse<0>(this, scan)的具体实现:
template<int N, typename DerivedT, typename ContextT, typename ScannerT>
inline typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type
grammar_parser_parse(
grammar<DerivedT, ContextT> const* self,
ScannerT const &scan)
{
//取得返回类型,还是调用parse_result,于其他parser类似。
typedef
typename parser_result<grammar<DerivedT, ContextT>, ScannerT>::type
result_t;
//definition类别,就是子类grammar类里的嵌套模板类definition
typedef typename DerivedT::template definition<ScannerT> definition_t;
result_t result;
// get_definition函数实际上就是构造一个子类grammar类里的嵌套模板类definition对象。
//并传入子类grammar本身,所以在definition类构造器里,应该定义所有的rule对象。
definition_t &def = get_definition<DerivedT, ContextT, ScannerT>(self);
//看看call_helper<N>::do_方法的具体实现。
call_helper<N>::do_(result, def, scan);
return result;
}
call_helper本身是一个模板类,我们在调用的时候一般是调用其特化版本:
template <>
struct call_helper<0> {
template <typename RT, typename DefinitionT, typename ScannerT>
static void
do_ (RT &result, DefinitionT &def, ScannerT const &scan)
{
//调用definition的start()方法,取得rule调用其parse方法,进入rule的parse流程
result = def.start().parse(scan);
}