boost.spirit -- scanner

2       scanner

2.1    scanner classes structure

 

 

scanner类是一个符号流扫描器,提供对输入符号流的读取,迭代,是否末尾的判断。

scanner提供的方法:

operator* (读取当前符号)

operator++ (移动到下一个符号)

at_end (是否到了当前符号流的末尾?)

scanner本身并不实现这些方法,而是将其委托给策略类来实现。策略类作为一个被继承的模板参数。

scanner的成员:

IteratorT first (迭代指示器:指向符号流的当前符号位置)

IteratorT end (迭代指示器:指向符号流的最末位置)

 

scanner模板类包含两个参数:

IteratorT:输入符号流的迭代器类型,默认为char const*,输入为字符串。

PoliciesT:策略类,scanner类从此类继承。

 

 

 

 

 

2.2    scanner_policies

 

scanner 策略类:scanner功能具体实现类;策略被横切为三种:迭代策略(iteration_policy),匹配策略(match_policy)和动作策略(action_policy)

 

2.2.1   迭代策略(iteration_policy)

scanner所提供的最主要功能,符号流的读取和迭代,都由此类完成。

方法实现概述:

at_end(scanner):判断是否到了符号流末尾;通过比较scanner的两个迭代指示器成员firstend是否相等。

advance(scanner):到符号流的下一个位置;++scanner.first

get(scanner):取当前符号;*scanner.first

filter(T):过滤当前符号;实际上,scanner::operator*()方法就是调用iteration_policy::filter(iteration_policy::get(scanner));get()方法得到的符号经过filter的过滤,这个方法的作用用于改变符号,比如想把输入的字符串全部改为大写再进行解析,就可以从iteration_policy类派生一个子类,重写filter方法,将字符to_upper就可以了。

 

2.2.1.1             upper_iteration_policy

upper_iteration_policy是一个自定义的迭代策略类,用于示范filter的用法。

 

// 模板类upper_iteration_policy,是为了把符号流中的所有字符都转为大写字符

// 这个类继承自BaseT (默认为iteration_policy),只改写filter方法,其他方法仍维持原语义。

template <typename BaseT = iteration_policy>

struct upper_iteration_policy :  public BaseT

{

    typedef BaseT base_t;

    upper_iteration_policy() : BaseT() {}

   

       //因为scanner_policiescopy ctor是调用各个基类copy ctor,包括iteration_policy的;如果要用upper_iteration_policy代替默认的iteration_policy,那么需要提供一个copy ctor。以便有人在写下scanner_policies< upper_iteration_policy, …> policy(scanner)时候不会出错。

    template <typename PolicyT>

    upper_iteration_policy(PolicyT const& other) : BaseT(other) {}

   

 

 

 

 

       // 提供一个filter方法,将所有读取出来的字符转为大写。

    template <typename T>

    T filter(T ch) const

    {

        printf("run this char:%c, and filter to:%c/n", ch, toupper(ch));

        return toupper(ch);

    }

};

 

template <typename DerivedT, typename ScannerT>

bool upper_parse(parser<DerivedT> const& p, ScannerT const & scan)

{

    // 替换scanner_policies的默认迭代策略类为自定义的upper_iteration_policy

    typedef scanner_policies<

        upper_iteration_policy<

                BOOST_DEDUCED_TYPENAME ScannerT::iteration_policy_t>,

        BOOST_DEDUCED_TYPENAME ScannerT::match_policy_t,

        BOOST_DEDUCED_TYPENAME ScannerT::action_policy_t

    > policies_t;

    /* 这是构造scanner的第一种方法,直接调用scanner的构造方法,注意这里的policies对象是通过scanner 对象构造的,实际上这是不必要的。

    scanner<BOOST_DEDUCED_TYPENAME ScannerT::iterator_t, policies_t>

    scan2(scan.first, scan.last, policies_t(scan));

    */

   

    // 或者无须重新构造一个新的scanner对象,直接在默认的scanner对象上调用change_policies方法,给他一个新的policies(前面替换的自定义policies)。实际上第2种方法使用比较广泛。

    match<nil_t> hit = p.derived().parse(scan.change_policies(policies_t()));

    cout << "hit:" << hit << endl;

    cout << "length:" << hit.length() << endl;

   

    return hit;

}

 

bool test_upper_parse(const char* str)

{  

    char const* last = str;

    while (*last) last++;

    scanner<char const*, scanner_policies<> > scan(str, last);

    return upper_parse(str_p("HEEL"), scan);

}

 

 

 

 

 

 

2.2.1.2             skipper_iteration_policy

skipper_iteration_policy  :跳过空格的迭代策略(系统提供)

这个策略重写了iteration_policy的大部分方法,包括advance,at_end

方法实现概述:

skip:跳过所有空格,一直到符号流末尾。

advance调用基类的advance,然后skip

at_end:先skip,然后调用基类的at_end判断是否到了末尾。

 

 

2.2.1.3             skip_parser_iteration_policy

skipper_iteration_policy策略类一样,也是跳过某些符号,只不过这些需要跳过的符号是由一个parser来解析的。

 

这个模板类有两个参数:ParserT,跳过字符的解析类;BaseT,继承基类。

该类继承自skipper_iteration_policy类,是为了继承其advanceat_end方法。

 

值得注意的是该类重写了基类的skip方法。这个方法是要来识别要跳过的字符。该方法调用skipper_skip(ParserT, scanner, scanner),该方法有三个重载,通过最后一个参数来区别实际的scanner类型;如果原来的scanner类中的迭代策略就是一个skipper_iteration_policy,那么这个函数需要把原来scanner中的skipper_iteration_policy去掉。

 

 

2.2.2   match_policy

匹配策略类,用来创建解析的结果类。

 

这个类首先要提供一个模板类result,用来推演parser的解析结果类。从meta function [1.2.3match_result]中得知,该函数需要一个MatchPolicyT参数,一般来说,该参数传入ScannerT,也就是match_policy(因为ScannerTmatch_policy派生而来)。这样,根据match_result的结果,应该为match_policy::template result<T>

 

方法概述:

no_match:错误match对象match<nil_t>()

empty_match:空的match对象match<nil_t>(0, nil_t())

create_match:创建一个match对象

group_match:未实现

concat_match:连接两个match对象

 

2.2.3   action_policy

动作策略类,这个类是为action对象提供的。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值