sed ってなんなの?

あーなんか言語紹介といえばこんなのがあったのでした。sed ってなんなのかという、とてもよくある疑問に対して私なりの回答です。まず実用を考えると、

sed 's/hoge/hage/'

このためだけに存在している言語です。メリットは perl -pe 's/hoge/hage/' より 4byte 短くてすむことだけです。これ以外の機能はスクリプト言語で十分なように思います。たまに勘違いしてる人がいる気がしますが、 y コマンドはカウンタを作るために存在しています。小文字を大文字に変換する、などと考えるとどのような時に使うのか皆目検討もつかず、ドツボにはまることうけあいです。気をつけましょう。ちょうど OOP を犬とか猫で教えるような話に似てるかもしれません。

で、 sed in depth 。 sed とはなにか? 誰がなんと言おうと、 sedVM です。以下に VM の仕様を示します。

命令セット(レジスタやメモリの移動系)

x
メモリとレジスタの入れ替え
h
レジスタからメモリにコピー
g
メモリからレジスタにコピー
H
レジスタからメモリのケツに追加
G
メモリからレジスタのケツに追加
d
レジスタをクリア

はい、どう見ても VM です。これ以降の命令はあんまり VM ぽくないので適当に。 :label で label ってラベルを作れて、 b label でそこに飛べます。おおアセンブラぽい。直前のマッチに成功していたらジャンプ、というのが t label でできます。えーとあとは p(rint) とか q(uit) とかはわかるかと。 print がある VM ってめずらしいねというツッコミは却下です。なぜなら ICFPC の UM はあったから。

で、とにかく重要なのは、普段 s/hoge/hige/ とかでやってる処理はレジスタでの処理だということです。で、 CISCアセンブラ書く人はわかってると思いますが、レジスタなんつーものは極めて短命です。 sed VM でも例外じゃないです。というかなんせ、1個しかレジスタが無いのですから、その大事度合いは x86 の 6 倍くらいになると予想されます。そこでメモリ領域があるのですが、恐ろしいことにこれも 1 つしかありません。しかし幸い、レジスタもメモリも文字列領域なので、基本的に無限長です。そこで、 1 つの空間を複数にわけて活用することになります。

そこまでわかっちゃえば、後は適当にメモリ内の 1行目はあの情報、2行目はあの情報、というような約束を決めて、毎回メモリから全データコピー→適当に正規表現で必要な情報を切り出す→処理→メモリのトップに返す→またメモリから拾ってる→とりあえずトップに返した情報を正しい位置に置く→メモリに返す、というサイクルを繰り返せば、とりあえず割と普通にプログラムができます。あとはエルフヘッダの知識と無駄に消費するための時間、ちょっとした工夫くらいがあればコンパイラも書けます!

で、えーと一応お約束なので。

$ {
 i Hello world!
}

どっちも説明してねー機能だった…

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h