言語を作る言語OMetaのPython版 PyMeta

http://ani.blueplane.jp/ume/121
http://d.hatena.ne.jp/propella/20071122/p1

OMetaっていうお手軽にプログラミング言語を作れる言語があるらしい.こいつが実はPythonでもPyMetaという名前で作られているっぽい.

Python好きで,時々プログラミング言語をちょこっと作ってみたいと思っている自分にはピッタリそうだ.

http://washort.twistedmatrix.com/

試しにHelloWorld的に出来るだけ素朴になるようS式の電卓を作ってみた.

from pymeta.grammar import OMeta

#文法の定義
scalcgrammar = """

digit  ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

number ::= (+):num => int(''.join(num))

opplus ::= '(' '+'  :f  :s ')' => f + s
opsub  ::= '(' '-'  :f  :s ')' => f - s
opmul  ::= '(' '*'  :f  :s ')' => f * s
opdiv  ::= '(' '/'  :f  :s ')' => f / s

sexp   ::=  |  |  |  | 

"""

#文法のクラスを作る
scalc = OMeta.makeGrammar(scalcgrammar, {})

#作った文法で計算
testcode = "(* (+ 1 2) (- 3 4))"
print "%s -> %d" % (testcode, scalc(testcode).apply("sexp"))

結果はこんな感じ.

(* (+ 1 2) (- 3 4)) -> -3

PEGっていう文法で文法を定義してそれをそのまま評価できる."=>"のあとにPythonの文法でパターンにマッチした内容を処理できる.単純に構文木を作るだけでもいいだろうし,その場で少し処理することもできる.今回は中間表現作らずにその場で計算するように作った.出来るだけ素朴に,その場で計算したいがために,演算子ごとに文法を分けてしまっているのがダサい.次回はもう少しスッキリするよう直してみよう.

作った文法をえらく簡単に試せるのでうれしい.そのうちSchemeインタプリタにまた挑戦してみようかと思う.