module Genlex:汎用字句解析器sig
..end
このモジュールでは、単純な「標準の」字句解析器を、文字のストリームからトークンのストリームへの関数として実装します。 この字句解析器は Caml の字句規約をおおよそ実装しつつ、目的の言語の予約語をパラメータとして与えることができるようになっています。
例: 電卓用の字句解析器は次のようにして作ることができます。
let lexer = make_lexer ["+";"-";"*";"/";"let";"="; "("; ")"]
これに対応する構文解析器は、 token stream
から、例えば int
への関数とすると、次のような規則を持ったものになるでしょう。
let parse_expr = parser
[< 'Int n >] -> n
| [< 'Kwd "("; n = parse_expr; 'Kwd ")" >] -> n
| [< n1 = parse_expr; n2 = parse_remainder n1 >] -> n2
and parse_remainder n1 = parser
[< 'Kwd "+"; n2 = parse_expr >] -> n1+n2
| ...
type
token =
| |
Kwd of |
| |
Ident of |
| |
Int of |
| |
Float of |
| |
String of |
| |
Char of |
Int
と Float
はそれぞれ整数と浮動小数点数です。
String
はダブルクォートでくくった文字列リテラルです。
Char
はシングルクォートでくくった文字リテラルです。
Ident
は識別子(英文字、数字、下線、クォートの並びか、 +
や *
といった「演算子文字」の並び)です。
Kwd
は予約語(識別子か、 (
や }
のような単一の特殊文字)です。val make_lexer : string list -> char Stream.t -> token Stream.t
s
がこのリストに含まれていた場合、戻り値のストリーム内でその識別子は Kwd s
になります。
そうでなければ Ident s
になります。
特殊文字 s
がこのリストに含まれていた場合、戻り値のストリーム内でその識別子は Kwd s
になります。
そうでなければ字句エラー(Parse_error
例外)が発生します。
空白と改行は読み飛ばされます。
(*
と *)
で区切られたコメントも同じく読み飛ばされます。
コメントは入れ子にすることができます。