blog.anqou.net
rss
author
tags

OCaml のコメントで文字列リテラルを閉じないと文法エラー

多くのプログラミング言語で、コメントには(コメント終端記号以外の)任意の文字列を書くことができます。

しかし実は OCaml にはコメントの中にかける文字列に制約があります。具体的には、文字列リテラル("...")を書く場合、必ずそのリテラルがトークンとして妥当でなければなりません。言い方を変えると、ダブルクオートの対応が取れている必要があります。

例えば以下のコードは正しいですが:

(* あ " いうえ " お *)

以下のコードは構文エラーになります:

(* あ " いうえ *)

ちなみにこれは quoted string({|...|})でも同様です[1]。以下は構文エラーになります:

(* あ {| いうえ *)

OCaml のソースコードを見に行くと、確かに文字列リテラルだけコメント中で特別に扱っています。履歴を辿ってみると OCaml 1.00 が出る前の段階(1995 年)でこの挙動に変更されているようでした

一体なぜこんな仕組みになっているのでしょうか。インターネットを調べると、プログラムを必ずコメントアウトできるようにするためという情報がありました(リンク 1リンク 2)。例えば次のようなコードを考えてみます:

print_string "*)";;

このコードをコメントアウトすると以下のようになります:

(*
print_string "*)";;
*)

もし " の対応を気にしない字句解析器なら print_string の引数の *) をコメントの終端と判定してしまい、コメントアウトが失敗してしまいます[2]。実際には "*)" がコメント中の文字列リテラルと判定されるため、安全にコメントアウトができるということになります。

注釈

  1. quoted string の取り扱いに関して utop v2.17.0 は壊れているらしく (* " *) と入力すると補完に何も表示されない(i.e., コメントの中と判定されている)のですが (* {| *) と入力するとコメントの外と判定されて補完が効くようになります。コントリビュートチャンスかもしれない。

  2. このブログで使っているシンタックスハイライトはまさにその挙動をしています。