言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

Fonc で遊ぶ

最近イアンの奴は Fonc と言ってるようです。これの peg を使って言語を作る実験をします。

準備

コンパイルして動作確認するまでの流れです。linuxmac を使います。(windows は挫折中)

$ svn co http://piumarta.com/svn2/idst/trunk/ idst
$ cd idst
$ make
$ cd function/jolt-burg
$ execstack -s main
$ cd ../examples/peg/
$ ../../jolt-burg/main boot.k peg.k -o calc.peg.k examples/calc.peg
; loading: boot.k
; loading: quasiquote.k
; loading: syntax.k
; loading: number.k
; loading: debug.k
; loading: object.k
; loading: yy.k
; loading: yy-compile.k
13 rules
parser written on calc.peg.k
$ ../../jolt-burg/main boot.k examples/calc.k
; loading: boot.k
; loading: quasiquote.k
; loading: syntax.k
; loading: number.k
; loading: debug.k
; loading: object.k
; loading: calc.peg.k
; loading: yy.k
> 3 + 4
7

超簡単な例

最初の calc の例でさえ難しいので、さらに簡単な例を考えます。標準入力から数字を一行読み取って返すだけです。先ほどのディレクトリに number.peg というファイルを作ります。

Numbers  = < [0-9]+ > { (printf "%s\n" yytext) }

%%
(yy-parse (yy-new [[StdIn readStream] prompt: '"> "]))

最初の行が文法です。数字の 0 から 9 までが一つ以上現れたら、それをプリントするという意味になります。yytext がマッチした文字列を表します。Number は非終端記号で、この場合何でも良いです。{} でくくった部分と %% 以降が coke の実行文です。意味は良く分かりませんが、とにかくこれで動くようです。

$ ../../jolt-burg/main boot.k peg.k -o number.peg.k number.peg
$ ../../jolt-burg/main boot.k number.peg.k
> 12345
12345

peg の動作を確認

これでは peg を使った感に乏しいので、冗長に書いてみます。

Numbers = (n:Number { (printf "%d" n) })+

Number = '0' { 0 }
       | '1' { 1 }
       | '2' { 2 }
       | '3' { 3 }
       | '4' { 4 }
       | '5' { 5 }
       | '6' { 6 }
       | '7' { 7 }
       | '8' { 8 }
       | '9' { 9 }

%%
(yy-parse (yy-new [[StdIn readStream] prompt: '"> "]))
(printf "\n")

今日はここまで。