Mongrel2とは関係なく「Ragel」……とも関係なくGarden Path Sentences
Mongrel2のsrc/http11/http11_parser.cを見てたら以下のようなコードがあった。
#line 454 "src/http11/http11_parser.c" switch( (*p) ) { case 33: goto st16; case 58: goto tr25; case 124: goto st16; case 126: goto st16; } if ( (*p) < 45 ) { if ( (*p) > 39 ) { if ( 42 <= (*p) && (*p) <= 43 ) goto st16; } else if ( (*p) >= 35 ) goto st16; } else if ( (*p) > 46 ) { if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) goto st16; } else if ( (*p) > 90 ) { if ( 94 <= (*p) && (*p) <= 122 ) goto st16; } else goto st16; } else goto st16; goto st0; tr25:
一目見て、人間が書いたコードじゃないし、何らかのパーサジェネレターが生成したのかなと思って、同じディレクトリを見てみると、拡張子が.rlのファイルがあって、ここにステートマシンや字句の定義がいろいろ書かれているっぽい。
よくよく見てみると、Rubyでも拡張ライブラリのJSONのパーサとかで.rlが使われている。
これは、「Ragel」という名前のソフトウェアらしいと分かった。Wikipediaによると、有限オートマトンをCやJava、Rubyなどのソースコードへコンパイルしてくれるものという。なるほどなぁ、複雑な状態を扱うソフトウェアって、こういうツールを使うのか。Wikipediaによると有限オートマトンの応用には、「半導体設計の自動化、通信プロトコル設計、構文解析などの工学面での応用がある。生物学や人工知能研究では状態機械(群)を使って神経系をモデル化し、言語学では自然言語の文法をモデル化したりする」とある。
パース(構文解析)のために有限オートマトンは広く使われてるってことで、Ragelもメジャーなのか。YaccやLexとどう違うんだろうか。
ともあれ、構文解析一般についてWikipediaを見ていたら、Garden Path Sentenceというのが出てきた。Wikipediaには対応する日本語のエントリがないのでググッてみたら、なんと、こんなマイナーネタなのにドイツ人の知人の顔が検索結果のトップに! というか、それはぼくが師の1人として崇める人の過去のブログエントリだった。思わずクリックして読んでみたら面白い話が。
“Make your love wand function better”
というスパムを受け取って、love wand functionって、どういう関数? ハッシュみたいなもの? と思ったそうだ。2秒ほどで、すぐに、あ、このfunctionは名詞じゃなくて動詞かと気付いたという話。ぼくは初見で当然動詞だと思ったと言うか、スパマーの比喩表現も分かったけど、それは多分日ごろfunctionという単語をどう使っているかという違いから来るんだろうな。
Garden Path Sentenceというのは、日本語では袋小路文とも言うようで、頭から読んでいったとき、当然こういう意味で読むだろうと読み進めるものの、最後で、構文解析に失敗したことに気付いてバックトラックして、違う解釈を試みるしかないような文ということらしい。庭の小道を案内するというのは、英語では人をミスリードするというような意味の慣用表現として使われるから、という。
Wikipediaには、こんな例がある。
The old man the boat.
ぱっと見ると、老人が、えっとボートをどうしたの? と思うんだけど、boatまで読み終わったところで、あ、manは動詞だったのねと分かる。the oldが主語。つまりこれは年老いた船長か何かが、乗組員を配置に付けるというなときに使われるであろう文。
日本語だと、
太郎は昨日買ったAndroidタブレットがクズだったので後悔している花子を笑った
後悔しているのは花子なんだけど、途中まで太郎のこととして読むのが自然なので、構文解析がセンテンスの後半で失敗する。こういうのは悪文の典型で、そもそも書いちゃいけない。
とか、Mongrel2のコードを読もうと思っていたのに、ぜんぜん関係なことばかりを調べてしまった……。