オレオレ言語と構文木によるトランスパイル?の実行環境を作りました

オレオレ言語と構文木によるトランスパイル?の実行環境を作りました

JSONパーサーを使えばLispっぽいオレオレ言語が作れるかも?と思い立ち、作ってみました。 せっかく構文木があるので、フローチャートも出力できるようにしました。

作ったもの

image

GitHubに使い方の説明があります。 ただ言語仕様の説明がないので、サンプルコードとソースコードのこのあたりを見ていただく必要があります。 FizzBuzzが動く最低限の文法しかないので難しくはないです。

フローチャート自動生成

image

今回の目玉機能です(?) ソースコードを解析して、フローチャートを生成・出力します。 画像生成にはGraphizのJS実装であるViz.jsを使っています。

仕組み

実は大したことは何もしていません。 誰もが普段使いしている物の組み合わせでプログラミング言語は作れます。

ググってみると同じような発想でプログラミング言語を作ってみた、という方はたくさん見つかります。

文法と構文解析

何はともあれプログラミング言語の文法を考えなくてはいけません。 文法には正解はなく、凝り始めると終わらない部分でもあります。 今回の目的は別のところにあったので、Lisp風の文法を採用します。

Lispの文法は先頭の命令に続いて引数が並ぶリスト構造なので、処理するのが楽です。 ポーランド記法に近い、というとイメージしやすいかもしれません。

Lisp風の文法を採用すると、言語がすでに構文木の形なので字句の解析でヒジョーに楽できます。 またLispはリスト構造なので、JSON.parseを使って構文木への変換まで行なっています。

実行

構文木ができてしまえば実行は非常に簡単です。 先頭の命令と後に続く引数を順に処理するだけです。

引数が値ではなく処理の場合があります(下記参照)。 先にその処理の結果を求めてから処理を続行する、という挙動は再帰で実現できます。

// $i に代入する値は $i+1 の結果
(:=, $i, (:+, $i, 1))

処理の流れはほとんどポーランド記法と同じことが見て取れると思います。

// ポーランド記法風に上のコードを表現(動きません)
= $i + $i 1

フローチャート生成

実はこちらもとても簡単に実現できます。 Viz.js(Graphiz)は図形の描画にdot言語というプログラムのようなコードを使います。 すでに構文木があるので、枝をたどりながらdot言語を生成しているのです。

Demoの[✏Draw]ボタンを押す前に、F12を押して開発者ツールを表示してください。 生成したdot言語がコンソールに出力されます。 これをViz.jsのライブデモに貼り付けるとフローチャートが描画されます。

digraph Flow {
    Object23[label="start", shape=circle];
    Object24[label="Out: \"hello, world.\"", shape=cds];
    Object25[label="end", shape=circle];
    Object23 -> Object24;
    Object24 -> Object25;
}

構文木から別の言語を生成する、というのは最近流行(?)のトランスパイラと同じことをやっている訳です。


謝辞
画像は Unsplash 様より使わせていただきました。