こんにちは、いっちゃんです。10ANTZでは、サーバーサイドのソフトウェア開発に携わっています。
本記事では、2025年3月10日に開催された社内勉強会の復習をします。10ANTZのエンジニアの間では不定期で勉強会が開催されており、業務と直接関係あるかどうかに関わらず幅広いテーマが取り上げられています。今回は、JSONで書ける自作プログラミング言語の開発というテーマで発表が実施されました。ここでは発表者による自作言語「ExprML」の開発について解説があり、これを通じて、JSONとJSON Schemaの活用、プログラミング言語開発に関する知見が共有されました。
以下では、この発表の内容について示した上で、共有された知見をまとめます。
目次
発表内容
JSONとJSON Schemaの基本
発表者の自作言語はJSON、JSON Schemaを活用したものとなっているため、まず、これらの基本的な事柄について説明がありました。
JSONは、広く普及した汎用データ記述フォーマットの一つで、以下のようにnull、数値、文字列、真理値、配列、オブジェクトを表現することができます。
1 |
null |
1 |
123 |
1 |
"abc" |
1 |
true |
1 |
[ null, 123, "abc", true ] |
1 |
{ "x": null, "y": 123, "z": "abc", "w": true } |
また、多くのプログラミング言語においてエンコーダ/デコーダ等のライブラリが提供されていたり、様々なエディタ・IDEにおいてシンタックスハイライトをかけることができたりします。そのため、特定の言語やフレームワークに依存しないものとなっています。JSONは実際あらゆる場面で利用されており、例えば、WEB APIのリクエスト/レスポンス、設定ファイル、構造化ログなどで利用されています。
JSON Schemaは、JSONの型や制約を規定するスキーマ言語です。多くのプログラミング言語においてJSON Schemaに基づくJSONデータのバリデーションを行うライブラリが利用可能です。また、多くのエディタ・IDEでJSON Schemaに基づくJSONファイルの静的チェックやコード補完などが利用可能です。以下はJSON Schemaに基づくJSONデータのバリデーションの例です。
1 2 3 4 5 6 7 8 9 |
// JSON Schema { "type": "object", "properties": { "name": { "type": "string" }, "age": { "type": "integer" }, "birthday": { "type": "string", "format": "date" } } } |
1 2 3 4 5 6 |
// JSON(NG) { "name": true, // <- Incorrect type. Expected "string". "age": -1.5, // <- Incorrect type. Expected "integer". "birthday": "not a date" // <- String is not a RFC3339 date. } |
1 2 3 4 5 6 |
// JSON(OK) { "name": "10ANTZ", "age": 11, "birthday": "2013-07-01" } |
以上の通り、JSONとJSON Schemaは、多くの言語でエンコーダ、デコーダ、バリデータ等が存在し、実装に組み込みやすく、また、テキスト形式であり、エディタ・IDE等のサポートも手厚いため、人間でも読み書きがしやすく、とても便利だと思います。
発表者の自作言語のコンセプト
発表者の自作言語「ExprML」は以下のコンセプトに基づいて開発されました。
- JSON(またはJSON互換のYAML)で書かれた式を評価できる。
- 他のプログラミング言語に組み込める。
1に関して、ExprMLは、例えば以下のソースコードを式として評価して、評価結果をJSONの値として返します。
1 2 |
true # => true |
1 2 |
-123.5 # => -123.5 |
1 2 |
"`string literal`" # => "string literal" |
1 2 |
arr: [3, 2, 1, 4] # => [3, 2, 1, 4] |
1 2 3 4 |
obj: x: "`abc`" y: 1015 # => { "x": "abc", "y": 1015 } |
1 2 |
not: true # => false |
1 2 |
lte: [123, 456] # => true |
1 2 |
cat: ["`a`", "`b`", "`c`"] # => "abc" |
1 2 3 4 5 6 7 |
eval: $hello: $name: "`ExprML`" where: - $hello($name): cat: ["`Hello, `", $name] # => "Hello, ExprML!" |
1 2 3 4 5 6 |
for($i, $e): arr: [4, 1, 3, 2, 5] do: $i if: gte: [$e, 3] # => [0, 2, 4] |
1 2 3 4 5 6 7 |
cases: - when: false then: 1 - when: true then: 2 - otherwise: 3 # => 2 |
2に関して、ExprMLは処理系を複数の言語で実装しており、Go、PHP、Dart、TypeScript/JavaScript、JVM言語からそれぞれライブラリとして利用可能となっています。
発表者の自作言語開発の概要
プログラミング言語の開発においては、以下を実施することが必要となります。
- 言語仕様の策定
- 処理系の実装
- コーディング環境の整備
1では、文法や動作を規定し、ドキュメント化します。2では、字句解析、構文解析、意味解析、評価(処理系がインタープリタである場合)/実行コード生成(処理系がコンパイラである場合)といった処理を実装します。字句解析はソースコードをトークン列に変換する処理です。構文解析はトークン列から抽象構文木を構築する処理です。意味解析は抽象構文木から実行するべき動作を決定する処理です。評価は決定した動作を実行する処理です。実行コード生成は決定した動作を実行するプログラムを出力する処理です。3では、シンタックスハイライト、静的チェック、コード補完といったソースコードの記述を支援する機能を提供します。
発表者は自作言語ExprMLをJSONの枠組みの中で開発しました。ここでは、1について、文法をJSON Schemaで記述することができます。2について、インタープリタの実装にあたり既存のJSONデコーダを利用することで字句解析と構文解析の実装を省略することができます。3について、文法が記述されたJSON Schemaを利用することで既存のエディタのコーディング支援機能を活用でき、新たにプラグイン等を実装する手間を省くことができます。
発表ではさらに、ExprMLの計算能力についてチューリング完全であることを示すためにExprMLでbrainfuckを実装するデモが実施されました。これは、あるプログラミング言語がチューリング完全であることを示すには、そのプログラミング言語により、すでにチューリング完全であることが分かっている別のプログラミング言語を実装できることを示せば良いという理屈によります。brainfuckはすでにチューリング完全であることが分かっているため、ExprMLもチューリング完全ということになると思います。
以上のように、発表者は自作言語開発において、JSONとJSON Schemaを活用する工夫により、チューリング完全なプログラミング言語を省力的に実装していると思います。
共有された知見
勉強会における発表を通して、以下の知見が共有されたと思います。
- JSONとJSON Schemaの基本的な知識、活用方法
- プログラミング言語を自作する上で触れることになる基礎知識
- プログラミング言語の計算能力を確かめる方法
まとめ
本記事では、社内勉強会で発表された自作言語開発についてまとめました。ここでは、まずJSONとJSON Schemaについて説明し、これに基づくJSONで書ける自作言語「ExprML」の開発について紹介しました。また、この発表を通じて共有されたJSON、JSON Schema、プログラミング言語開発に関する知見をまとめました。
関連リンク
- JSON:https://www.json.org/json-en.html
- JSON Schema:https://json-schema.org/
- ExprML:https://github.com/exprml/exprml-language