| 詳細:スキャナ |
![]() |
![]() |
![]() |
| scanner クラス | |||||||||
value_t |
typedef:スキャナが用いるイテレータの値の型 | ref_t |
typedef:スキャナが用いるイテレータの参照型 | bool at_end()
const |
入力が尽きていれば真を返す | value_t operator*()
const |
参照はがし/入力から value_t を取得する |
scanner
const& operator++() |
スキャナを前方に進める |
IteratorT& first |
現在の入力位置を指すイテレータ。参照で保持される | ||||||||
IteratorT const
last |
入力の末尾を指すイテレータ。値で保持される | ||||||||
スキャナの基本的な振る舞いはポリシーによって扱われる。 上の表に挙げられているスキャナの公開メンバ関数の実際の実行はスキャナポリシーによって実装されている。
三つのポリシーの組みがスキャナの振る舞いを司る。 これらのポリシーは煩わしいことなく Spirit を拡張することを可能とする。 スキャナポリシーは、潜在的に不安定化の要因となるコードの変更をすることなしに、中核機能を拡張できるようにする。 ライブラリ作成者は、構文解析処理を自分の要求に沿うよう詳細に調整するために、既存のものを上書きする独自のポリシーを提供してもよい。 コアレイヤーより上のレイヤーもこのポリシーを基礎とした機構の利点を得ることができる。 抽象構文木(abstract syntax tree)の生成、デバッガ、それにレキサが思い浮かぶ。
ポリシーには三つの組があり、それぞれ以下を司る:
以下はイテレーションとフィルタリングを司るデフォルトのポリシーである:
struct iteration_policy
{
template <typename ScannerT>
void
advance(ScannerT const& scan) const
{ ++scan.first; }
template <typename ScannerT>
bool at_end(ScannerT const& scan) const
{ return scan.first == scan.last; }
template <typename T>
T filter(T ch) const
{ return ch; }
template <typename ScannerT>
typename ScannerT::ref_t
get(ScannerT const& scan) const
{ return *scan.first; }
};
| イテレーションポリシーとフィルタリングポリシー | |||||||
| advance | イテレータを前方に進める | at_end | 入力が尽きていれば真を返す | filter | 入力から読み込まれた文字をフィルターする | get | 入力から文字を読み込む |
次のコード断片は、すべての文字を小文字に変換する単純なポリシーを示す:
struct inhibit_case_iteration_policy : public iteration_policy
{
template <typename CharT>
CharT filter(CharT ch) const
{ return std::tolower(ch); }
};
以下は、認識とマッチングを司るデフォルトのポリシーである:
struct match_policy
{
template <typename T>
struct result { typedef match<T> type; };
const match<nil_t>
no_match() const
{ return match<nil_t>(); }
const match<nil_t>
empty_match() const
{ return match<nil_t>(0, nil_t()); }
template <typename AttrT, typename IteratorT>
match<AttrT>
create_match(
unsigned length,
AttrT const& val,
IteratorT const& /*first*/,
IteratorT const& /*last*/) const
{ return match<AttrT>(length, val); }
template <typename MatchT, typename IteratorT>
void
group_match(
MatchT& /*m*/,
parser_id const& /*id*/,
IteratorT const& /*first*/,
IteratorT const& /*last*/) const {}
template <typename Match1T, typename Match2T>
void
concat_match(Match1T& l, Match2T const& r) const
{ l.concat(r); }
};
| 認識とマッチング | |||||||||||
| result | 与えられた属性型に従ってマッチ型を返すメタ関数(詳細:パーサを参照) | no_match | 失敗したマッチを作成する | empty_match | 空のマッチを作成する。空のマッチは成功したεマッチ(マッチ長さ == 0)である。 | create_match | 与えられたマッチング長に応じたマッチ、属性、および入力のマッチ部を指すイテレータの組を作成する。 | group_match | 一致判定に成功した後に、ルールなどの非終端記号に対して後処理を許すために呼び出される。 | concat_match | 二つの一致判定オブジェクトを連結する。 |
アクションポリシーはセマンティックアクションを扱うためのただ一つの関数を持つ:
struct action_policy
{
template <typename ActorT, typename AttrT, typename IteratorT>
void
do_action(
ActorT const& actor,
AttrT const& val,
IteratorT const& first,
IteratorT const& last) const;
};
デフォルトのアクションポリシーは、もし val 属性の型が nil_t ならば、以下に送られる:
actor(first, last);
さもなくば以下のようになる:
actor(val);
scanner_policies クラスは上述の三つのスキャナポリシークラスを一つに連結する:
template <
typename IterationPolicyT = iteration_policy,
typename MatchPolicyT = match_policy,
typename ActionPolicyT = action_policy>
struct scanner_policies;
この mixer クラスは三つのポリシー全てを継承する。 その後、この scanner_policies クラスはスキャナをパラメータ化するために用いられる:
template <
typename IteratorT = char const*,
typename PoliciesT = scanner_policies<> >
class scanner;
次にスキャナが PoliciesT を継承する。
スキャナは異なるポリシーの組にいつでも再束縛されることができる。 スキャナはメンバ関数 change_policies(new_policies) を持つ。 新しいポリシーの組を与えると、このメンバ関数はその新しいポリシーの組を持った新しいスキャナを作成する。 再束縛されたスキャナの結果の型は次のメタ関数を呼ぶことによって取得できる:
rebind_scanner_policies<ScannerT, PoliciesT>::type
スキャナは異なるイテレータ型にいつでも再束縛されることができる。 スキャナはメンバ関数 change_iterator(first, last) を持つ。 スキャナの保持するものと異なる型のイテレータの組を与えると、このメンバ関数はその新しいイテレータの組を持った新しいスキャナを作成する。 再束縛されたスキャナの結果の型は次のメタ関数を呼ぶことによって取得できる:
rebind_scanner_iterator<ScannerT, IteratorT>::type
![]() |
![]() |
![]() |
Copyright © 1998-2003 Joel de Guzman
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided "as is" without express or implied warranty, and with
no claim as to its suitability for any purpose.
Japanese Translation Copyright © 2003 Kent.N
オリジナルの、及びこの著作権表示が全ての複製の中に現れる限り、この文書の複製、利用、変更、販売そして配布を認める。このドキュメントは「あるがまま」に提供されており、いかなる明示的、暗黙的保証も行わない。また、いかなる目的に対しても、その利用が適していることを関知しない。
このドキュメントの対象: Boost Version 1.30.0
最新版ドキュメント(英語)