[Haskell] 関数型言語 Gofer のソースを読む(2)

この記事は、私のメモのようなものですが、少しだけ Gofer処理系全体に付いて書くと、 論文に書かれている Gofer の内部構造は以下の図のようになっています。また、処理系はMS-DOSレベルのマシンでも動くように作られているようで、prelude.hにSAMLL_GOFER, REGULAR_GOFER, LARGE_GOFERというdefineがあり、この定義を変える事で前回説明した各エリアの大きさが変わるようになっています。

今日は、5章 Lexical analysis and parsingを読みました。対応するソースは input.c と parser.y です。この部分はコンパイラーやインタプリターを作った・学んだ方なら比較的わかりやすい部分だと思います。 Gofer では字句解析は Input.c の中にC言語での独自実装されていますが、構文解析yacc を使っています。

input.c にはGoferのプログラムをコンソールやファイルから読むための関数なども含まれています。字句解析は1文字先読みしながらトップダウンで字句を解析しています。 yacc で書かれた構文解析Haskellをそのままパース出来るようになっており、既存の Haskell プログラムを利用できるようになっています。ただし、構文解釈は多少Haskellとは違うそうですが、この辺の違いは理解できませんでした ^^;

また、yaccはトークンを1つしか先読みしないので、一部のHaskellの構文は正しく解釈できません。そこで paraser.yの最後にある shift-reduce parserをベースにしたtidyInfix関数で調整しています...これも理解できていません ^^;
さらに、Haskellのインデントによるブロックを { ... ; ... } に置き換えたりするアドホックなコードなどもあります。それから、GCからyaccの状態を保護する為の shadow スタック関数(マクロ)なども parase.y 内に頻繁に登場します。


論文の5章後半に書かれている事がよく理解出来ないので、改めて ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門 を読んでいます。だんだんとHaskellに入り込み難易度が高くなっています・・・・・・

Gofer をMacで動かしてみる

やはり、Goferを動かしたくなり、 Mac (Leopard)でコンパイルして動かしてみました。
そのままではコンパイルエラーになったので、 prelude.h の machine/compiler 選択を NETBSD にしたところ動きました。
また、そのままでは GNU Readlineが使えないので #define USE_READLINE 1 にし、Makefile の LDFLAGS に -lreadline を追加する事で Readline も使えるようになりました。