俺の色に染めてやる的な
サイトを色々弄りたいという欲求もだいたい落ち着いたので、ソースコードに色を付けることを考える。
- コメント
- 文字列,正規表現リテラル
- 予約語
色を付ける対象はこれぐらい。
真っ当にやるなら字句解析だろう。 言語それぞれの規則に応じて字句解析し、その結果として得られる各要素の種別に応じて色を付け、ソースコードを再構築する。 字句解析のライブラリも、ちょっと検索すれば色々見つかるし。
でも巷の字句解析って、その後に構文解析をつなげる前提で、空白を捨てるのが多いんだよな。 この仕様が、今回のようにただ色を付けたいだけの場合にはマイナスになる。 目的はソースコードの整形やパースじゃなくて色をつけることなので、空白は空白でそのまま残しておく必要があるのだ。
字句解析の結果として、各要素が何文字目から何文字目までという情報を付けてくれるものもあったが、これはこれで微妙。 この情報から分かるのは捨てられた文字数だけで、捨てた文字が半角空白だったのかタブ文字だったのかは判らない。 解析前と照合すればいいのだが、それもなぁ…。
そして何より、他人の作ったライブラリを使うと、俺の作りたい欲求が満たされないままだ。 が、構文規則を食わせて字句解析ツールを生成する処理から始める程にガッツリ作りたいわけでもないんだよな。
ということで、大雑把だが、以下の方針でやることにした。
- 処理対象のソースコードが文法・構文的に正しいことを前提とする。
- 色を付けたい要素を直接探し出して色を付ける。
直接探し出すのは、たぶん正規表現でいけるだろう。
- コメントや文字列など、複数の単語を持つ領域をまず最初に探し出して切り分ける。
- 残った部分に対して、予約語を探し出して切り分ける。
- 探し出したそれぞれに、その種別に応じた色を付けて再結合する。
まだふわふわだが、たぶんこんな感じでいける気がする。
コメントや文字列を先に処理するのは、その中に予約語と同じ文字列を含む可能性があるから。 予約語を先に処理しようとすると、見つけた予約語が本当に予約語なのか文字列の中なのかというコンテキストを個別に判別しなきゃいけなくなる。 予約語と同じ字面だけど予約語ではない可能性は、先に排除しておくのが吉だろう。
もっとプログラム寄りで表現するなら、ソースコードの構成を
ソースコード = ( コメント | 文字列 | 正規表現リテラル | その他の要素 )*
その他の要素 = ( 予約語 | 更にその他の要素 )*
と見立てて、これらの構成要素をこの優先順で解析していくということ。 なんかBNFっぽい気もするが、きっと気のせいだ。
続きは明日。 まずは対象言語をJavaScriptで実装してみる。