2021-12-21に更新

なでしこ3でかんたんな自作言語のコンパイラを書いた

日本語プログラミング言語「なでしこ」 Advent Calendar 2021
https://qiita.com/advent-calendar/2021/nadesiko
の13日目の記事です。

image

ライフゲームのコンパイルが通ればヨシ、という程度の雑なものです。

https://github.com/sonota88/vm2gol-v2-nadesiko3

移植元

https://github.com/sonota88/vm2gol-v2

なでしこ3版のベースになっているバージョンは tag:62 のあたり

<自作言語処理系の説明用テンプレ>

自分がコンパイラ実装に入門するために作った素朴なトイ言語とその処理系です。簡単に概要を書くと下記のような感じ。

<説明用テンプレおわり>

メモ

なでしこ3版のサイズ(行数)はこれくらい。1,000行切ってますね。

$ wc -l *.nako3 lib/*.nako3
  365 codegen.nako3
  110 lexer.nako3
  422 parser.nako3
   49 lib/utils.nako3
  946 合計
  • そんなに苦労しなかった
    • 書き味は普通にスクリプト言語っぽい感じ
    • 標準でJSON読み書きできる、ネストした配列が作れる
    • [1, "a", []] のように JavaScript っぽくリテラルが書ける
  • ファイル分割できない?
    • ナデシコ命令を使って分割したファイルの取込み(というか読み込んだコードの評価)ができないか軽く試したのですが、期待した動きにならなかったので、諦めて適当なスクリプト(preproc.rb)で前処理することに

引数+助詞、引数+助詞、 ... 関数。 のように書くのだ、ということをまず最初に知ると基本的な読み書きができるようになります。

命令文の基本的な文形 *
そして、なでしこのプログラムの構造は、以下のような形式になっています。
引数+助詞、引数+助詞、 ... 関数。
『「こんにちは」と表示』という命令文で言えば、「こんにちは」が引数で、「表示」が関数となります。

「読んで」が んで に別れる、みたいなのもあって最初はよく分からなかった気がするので、助詞一覧にも目を通しておくとよいです。

予約語や助詞はハイライトがあるといいなと思って、 Emacs の generic-mode で色を付けて書いていました。最初は助詞一覧が頭に入ってないので、エディタのサポートがあると入門がスムーズになるように思います。Qiita のコードブロックでもサポートされるといいですね。

0044.png


最初は慣れてなくて試行錯誤が少しありました、という例をメモ。

# 「変数宣言パース」はトークン列をパースして変数宣言文オブジェクトを返す自作関数
# 「文リスト」は配列
変数宣言パースして文リストに配列追加

変数宣言パース 関数の戻り値を 文リスト に追加したいのですが、これは文法エラーになります。

マニュアルの 「配列追加」命令 の説明に書かれているように、AにBを または Aへ の形で引数を渡さなければいけない(関数定義で定められた通りに助詞を添えなければいけない)からです。

ふーむ、なるほど、ということで次のように一時変数を補って2行(2文?)に分けると AにBを配列追加 の形になり、動くようになります。

変数宣言パースして文に代入
文リストに文を配列追加

1行で書けないでしょうか?

# () はなくてもOK
文リストに(変数宣言パース)を配列追加

1行で書けるようになりました。でもなんか微妙ですね……:thinking:

こういう場合は、「それ」を使うと AにBを配列追加 の形に持ち込むことができます。

変数宣言パースして、文リストにそれを配列追加

# 「Aに」「Bを」の順番は入れ替えてもよい
変数宣言パースして、それを文リストに配列追加

自然になりました。なるほど、こう書けばいいのかー。


なでしこ3には敬語があります。

なでしこv3.1.14以降、なでしこで礼節をわきまえたプログラムを書くことができるようになりました。

使ってみました。なでしこ3では礼節のあるコンパイラを書くことができます。

パースして抽象構文木に代入してください。
抽象構文木をJSONエンコードして、それを表示してください。お願いします。

この記事を読んだ人はこちらも(たぶん)読んでいます

Originally published at qiita.com
ツイッターでシェア
みんなに共有、忘れないようにメモ

sonota486

Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

有料記事を販売できるようになりました!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?

コメント