03

19

[C++] デシリアライザクラス その1

2012.03.19(18:31)

教材を作っています。

ある仕様に基づき、与えられたASCII文字列からバイナリーデータを作り出すクラスを作ります。拡張BNF記法~字句解析~構文解析、C言語のポインタ、C++言語のクラス、オブジェクト指向設計、どう実装するか、どうテストケースを書くのか、そのテストケースでほんとうに良いのか、に対する教材とするつもりでいます。

適度にやさしく、適度に難しく、いろいろ考えさせるような問題作りをめざします。しかしながら、まだ実装もできていないので、行き詰まる可能性もあります。


問題は以下のとおり。拡張BNF記法で記述する。
<ポインタ>::="["[<メンバ>(","<メンバ>)]"]"
<メンバ>::=(<数>|<ポインタ>)
<数>::="0x"<HEX><HEX><HEX><HEX><HEX><HEX><HEX><HEX>
<HEX>::="0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
  |"a"|"b"|"c"|"d"|"e"|"f"|"A"|"B"|"C"|"D"|"E"|"F"
とし、
<数>は、ASCIIからバイナリに変換してバッファ上に配置する。
<ポインタ>は、もし"[]"であればNULLを配置し、そのNULLを配置したアドレスを返す。
fig[]
<ポインタ>は、もし"[0x00000001]"であればuint32_tの1を配置し、その1を配置したアドレスを返す。
fig[1]
<ポインタ>は、もし"[0x00000001,[0x00000002]]"であれば、uint32_tの1があって、次のアドレスにポインタが入っていて、そのポインタの先にuint32_tの2があるようなバイナリデータ列を作り、1を配置したアドレスを返す。
fig[1[2]]
2を配置する場所は複数考えられるが、無駄なメモリが少なくなるなら、どこに配置してもかまわない。上記は一例。以下同様。
"[0x00000001,[0x00000002],[0x00000003]]"の場合、1の次のアドレスと次の次のアドレスにポインタがあり、それぞれが2と3をさしているように配置して、1を配置したアドレスを返す。
fig[1[2][3]]
"[0x00000001,[0x00000002,[0x00000003]]]"の場合
fig[1[2[3]]]
"[0x00000001,0x00000002,[0x00000003,0x00000004,[0x00000005,0x00000006],0x00000007,0x00000008],
0x00000009,0x0000000a]"の場合(画像をクリックすると全体が見えます)
fig[12[34[56]78]910]

<ポインタ>として与えられたASCIIで記述された文字列から、C言語のポインタがアクセスできるバイナリのデータを作る。あとあとの実装とテストをラクにするため、<数>は4バイト符号なし整数(uint32_t)だけ、<ポインタ>の長さは4バイトとし<数>の長さと同じ、あとは適当にC言語同様の仕様とする。

ポインタの先に、数が1つだけなら、数へのポインタ。ポインタの先に、数やポインタが複数あれば、構造体へのポインタである。構造体のメンバには数も他の構造体へのポインタもある。

その2へ続く (実装しながら、これから書きます。)
プロフィール

島敏博

Shima Toshihiro 島敏博
信州アルプスハイランド在住。HaskellとElixirが好き。組み込みソフトウェアアーキテクト、C++プログラマ、山歩き、美術館巡り、和食食べ歩き、日本赤十字社救急法指導員、インデックス投資、クラシック音楽、SESSAME会員、状態マシン設計、モデル駆動開発、ソフトウェアプロダクトライン、Rubyist、実践ビジネス英語

■ ツイッター
http://twitter.com/saltheads
■ Facebook
http://www.facebook.com/saltheads
■ Qiita
http://qiita.com/saltheads

印刷する場合は、ブラウザの印刷メニューではなく、このページの上から3cmくらいの青いところにある、「印刷」を押してみてください。少しうまく印刷できます。まだ完全ではないのですが、これで勘弁してください。


カテゴリ
最新記事
月別アーカイブ
最新コメント
検索フォーム
リンク
sessame
RSSリンクの表示