超訳なので、間違いがあるかもしれませんの。
10.1 C++パーサー
10.1.1 C++ Bisonインターフェイス
LALRパーサーを c++ で作るときは スケルトンディレクティブ '%skeleton "lalr1.c"’ を使ってくれ。コマンドラインオプション --skeleton=lalr1.c でもおk。
実行したら bison は、各々のエントリを yy 名前空間上に作るぜ。'%define namespace' ディレクティブを使ったら変更できる。
いくつかのクラスも作成される。
position.hh location.hh
位置トラッキング用のポジションとロケーションの定義ファイル。C++ロケーション値のとこもみてくれや。
stack.hh
パーサーが使うスタックの補助クラス。
file.hh file.cc
(入力ファイルの拡張子が .yy のときな) C++パーサークラスの、宣言と定義。2個のファイルのベース名と拡張子はCパーサーとおんなじルールで作成される。
ヘッダが必要なときは -d/--defines オプション指定するか、%defines ディレクティブな。
10.1.2 C++で定義されてる値
%union ディレクティブはCでちゃんと動くように作ってある。具体的には、ちゃんとした union を生成する。C++だといくつかの特性がある。
- YYSTYPEが定義されてるけど、それはお勧めできない。パーサーにカプセルされた yy::parser::semantic_type を使うようにしてくれ。
- POD (Plain Old Data) じゃないと使われへん。C++は union の中でコンストラクタを持ったクラスの実体化を禁止しとる。ポインタやったらいけるで。
オブジェクトをポインタでおいといたら、メモリは自動的に再生されへんで:%destructor ディレクティブを使ってもそれはメモリリークを避けるためだけやしね。
10.1.3 C++ロケーション値
%locations ディレクティブを使ったら C++ パーサーにロケーショントラッキング機能が追加されるで。詳しいのはロケーション概要を見といてくれ。2個の補助クラス position (ファイル中の位置を示す)と、location(ポジションのペアから成るレンジ)が作成される。(いくつかのファイルにまたがる可能性がある)
10.1.4 C++パーサーインターフェイス
出力される output.hh と output.cc の、名前空間 yy 内にパーサークラスの宣言と定義がある。クラス名のデフォルトは parser やけど、%define parser_class_name "name" で変えられる。クラスのインターフェイスの詳細は後で書くけど、%parse-param を使うと拡張できる。こいつの動作は、パーサークラスにメンバーを追加して、コンストラクタに引数を追加するちょっとの処理。
- 型 parser: semantic_type
- 型 parser: location_type
意味値と位置値。
- 関数 parser: parser (type1 arg1, ...)
新しいパーサーオブジェクトを作成する。引数なしがデフォルト、%parser-param {type1 arg1} が使われてたらこうなる。
- 関数 parser: int parse ()
構文解析の実行、0がかえってきたら成功で、1だったらその他。
- 関数 parser: std::ostream& debug_stream ()
- 関数 parser: void set_debug_stream (std::ostream& o)
パース追跡時に使われるストリームの設定/取得。デフォルトは std::cerr。
- 関数 parser: debug_level_type debug_level ()
- 関数 parser: void set_debug_level (debug_level l)
追跡レベルの設定/取得。0だと追跡なし、0じゃなかったら、フルに追跡じゃ。
- 関数 parser: void error (const location_type& l, const std::string& m)
このメンバ関数はユーザー側で作らなあかん。パーサーはエラーをどこで起きたかを l、内容を m として呼び出す。