Open2
OCaml で 構文解析/字句解析
環境構築とか
- OCaml version 5.3.0
- Libraries
- menhir 20240715
- dune 3.18.0
使用するライブラリをインストール
opam install menhir dune
dune でプロジェクトを作成
dune init project <project_name>
lib フォルダ内に以下のファイルを作成
parser.mly
lexer.mll
lib/dune に以下を追記.ライブラリ名なども決めてあげるとよい
(ocamllex lexer)
(menhir
(modules parser))
Ocamllex の扱いを学ぶ
- lexer.mll の中に規則を書いていく.(lexなどと似ている感じ)
- lexer.mllの中身はヘッダ,規則部,トレイラーに分かれる
トークン列に分解してみる
スペース or 改行を区切り文字として文字列を分解するだけのシンプルなトークナイザを作ってみる
syntax.ml
type program =
| Eof
| Text of string
let print_program p =
match p with
| Eof -> print_newline ()
| Text (text) -> print_string text; print_newline ()
lexer.mll
let whitespace = [' ' '\n' '\r']
rule main = parse
(* ignore spacing and newline characters *)
whitespace+ { main lexbuf }
| ['a'-'z' '0'-'9' '_' '\'']* as lexeme { Parser.Text lexeme }
| eof { Parser.Eof }
| _ { Parser.Eof }
parser.mly
%{
open Syntax
%}
%token Eof
%token <string> Text
%start <program> toplevel
%%
toplevel :
| Eof { Eof }
| Text { Text ($1) }
main.ml
let () =
let lexbuf = Lexing.from_channel stdin in
try
while true do
let program = Lang01.Parser.toplevel Lang01.Lexer.main lexbuf in
Lang01.Syntax.print_program program;
done
with _ ->
exit 0;
いろんなサイトのサンプルコードを適当に弄っただけではあるが,改行や空白に分割することは一応できた.ちょっとずつ ocamllex を使った字句解析の流れも掴めた.
さて,ここまでやってみて気がついたのだが,ocamllex ではマルチバイト文字は扱えないらしい?日本語などのマルチバイト文字を扱いたければ sedlex という別のライブラリを使う必要があるらしい.
まあ,OCaml で字句解析をするとなれば ocamllex がチュートリアルみたいなもんだし...