リファレンスのトップ



大項目 記法 説明 返り値と変数への代入(Attribute)
スキップ無視ディレクティブ
Parser Directive Inhibiting Skipping 
lexeme[p]  スキップ機能をオフにします。ただし、他のパーサと同様に先頭のスキップは行います。
使用ケースとしては、phrase_parse()関数でパースする場合です。
例:
phrase_parse()で、スキップ(skipper)にqi::space、入力文字列を以下の場合。
入力: " 123 78"
・+qi::char_ ⇒ "12378"
・lexeme[+qi::char_] ⇒ "123 78"
・no_skip[+qi::char_] ⇒ " 123 78"
p: P --> lexeme[p]: P
p: Unused --> lexeme[p]: Unused
パーサpが代入に使用されない場合は、全体の返り値も代入されない。
パーサpが代入される場合は同じ値を代入する。
全スキップ無視ディレクティブ
Parser Directive Inhibiting Skipping Without Pre-skip 
no_skip[p] 全てのスキップを無視します。
lexemeとの違いは、lexemeが先頭のスキップは無視しないのに対し、このディレクティブは、先頭のスキップも無視する点です。
使用ケースとしては、phrase_parse()関数でパースする場合です。
例:
phrase_parse()で、skipperにqi::space、入力文字列を以下の場合。
入力: " 123 78"
・+qi::char_ ⇒ "12378"
・lexeme[+qi::char_] ⇒ "123 78"
・no_skip[+qi::char_] ⇒ " 123 78"
p: P --> no_skip[p]: P
p: Unused --> no_skip[p]: Unused
パーサpが代入に使用されない場合は、全体の返り値も代入されない。
パーサpが代入される場合は同じ値を代入する。
大文字小文字を無視するディレクティブ
Parser Directive Inhibiting Case Sensitivity 
no_case[p]  このディレクティブは、どのような入力に対してもカーソルを移動しない。サブジェクトパーサが大文字小文字を区別しないように強要することが目的である。 p: P --> ns::no_case[p]: P
p: Unused --> ns::no_case[p]: Unused
パーサpが代入に使用されない場合は、全体の返り値も代入されない。
パーサpが代入される場合は同じ値を代入する。
属性を無視するディレクティブ
Parser Directive Ignoring Attribute 
omit[p]  主題のパーサの返り値がunusedになるように、属性をを無視する。??
読み取りを無視する模様。
unused_type


全体 ⇒ 代入しない
p ⇒ 代入しない
非属性化ディレクティブ
Directive for Transduction Parsing (raw[])
raw[p]

??パーサpの返り値を無視し、代わりにpでマッチした全体の、開始と終了の2つのiteratorを返します。
旧spiritに近い動作にすることができます。


パーサpの中身がたくさんのパーサがあるときに使用するものと思われます。
例: 入力は、"James007"
raw[(alpha | '_') >> *(alnum | '_')]
⇒ 入力"James007" のiteratorで、先頭と最後の2つを返します。

a: A --> raw[a]: boost::iterator_range<Iter>
a: Unused --> raw[a]: Unused
全体 ⇒ マッチ箇所の文字列
p ⇒ 代入しない
Repetition Parser Directive (repeat[]) パワフルで柔軟性のあるパーサの繰り返しを提供します。
 
  repeat[p] 0回以上の繰り返し。 p: P --> repeat[p]: vector<P>
p: Unused --> repeat[p]: Unused
  repeat(n)[p] n回の繰り返し。 p: P --> repeat(n)[p]: vector<P>
p: Unused --> repeat(n)[p]: Unused
  repeat(min, max)[p] min以上max以下の繰り返し。 p: P --> repeat(min, max)[p]: vector<P>
p: Unused --> repeat(min, max)[p]: Unused
  repeat(min, inf)[p] min以上の繰り返し。繰り返し回数は無限。
繰り返す回数は、失敗するまでか、入力が終わるまで。
例: 文字aの10以上の繰り返し。
qi::repeat(10, qi::inf)["a"] 
p: P --> repeat(min, inf)[p]: vector<P>
p: Unused --> repeat(min, inf)[p]: Unused
パーサテストディレクティブ
Directive Testing if Parser Succeeded (matches[])
matches[p]  pのパーサを実行して、マッチしたかどうか(true/false)を返します。 boolを返す。
スキップ再設定パーサ
Parser Directive Re-Establishing Skipping (skip[])
スキップをするようになります。 test_parser("1, 2, 3, 4, 5", skip(space)[int_ >> *(',' >> int_)]);
  skip[p] lexeme[]やno_skip[]で無効化したスキップを元に戻します。
主にphrase_parse()関数で使用することになると思います。
p: P --> skip[p]: P
p: Unused --> skip[p]: Unused
  skip(c)[p] パーサcにマッチした文字をスキップします。先頭でもスキップします。
例:入力" 1, 2, 3, 4, 5"に対して。
qi::skip(qi::space)[qi::int_ >> *(',' >> qi::int_)]
p: P --> skip(c)[p]: P
p: Unused --> skip(c)[p]: Unused
返り値代入管理ディレクティブ
Parser Directive for Attribute Commit/Rollback (hold[])
hold[p] これは、返り値の管理を助けます。
通常、パイプ(|)パーサが先頭に戻ってパースし直す場合、返り値の代入は自動ではリセットされません。
例えば、以下のパースを入力文字列"MM"に対して行う場合、
全体の結果としてどのような返り値が出来上がると思いますか?
(qi::alnum >> qi::alnum >> qi::alpha)
| (qi::alnum >> qi::alnum);
答えは、"MMMM"です。直感と違いますよね?
説明:
上記のパースの形式は、「パース① |パース ②」という記述の仕方です。
最初のパース①(qi::alnum >> qi::alnum >> qi::alpha)の中では、最初の2つのqi::alnumはマッチするので、返り値"MM"が保管されます。最後の3つ目は、入力文字が存在しないため、失敗し、保管が行われません。
しかし、失敗しているのにも関わらず、保管は"MM"のまま、②の1つ目、2つ目のqi::alnumの検査をして、それぞれの返り値が保管され、結果"MMMM
"となります。
"MM"を返したい場合は、以下のようにします。
hold[(qi::alnum >> qi::alnum >> qi::alpha)] | (qi::alnum >> qi::alnum);
⇒hold内の保管は、実際の保管場所とは違う場所に保管され、マッチした時に実際の保管場所にコピーされます。マッチしない場合は破棄されます。
p: P --> hold[p]: P
p: Unused --> hold[p]: Unused

Parser Directives Forcing Atomic Assignment (as<T>, as_string[], as_wstring[])  
  as<T>()[p] 型Tのコンテナ(vector<T>など)の一時オブジェクトを生成します。パーサpを実行し、結果、コンテナを返り値として返します。もしパーサpがマッチした場合、コンテナをattrに割り当てます。 a: A --> as<T>()[a]: T
  as_string[a] as<std::string>()[a] と同じです。 同上
  as_wstring[a] as<std::wstring>()[a] と同じです。 同上