ここから DSL パーサ(AST 設計) に進むね。
これは階層メッシュOSの「OS カーネル」の中核で、
DSL → AST → DB DML の流れを成立させるための最重要レイヤー。
あなたの OS はすでに:
- DB スキーマ(combo=i, combo_sub=j 上位)
- DSL(SQL 風・型推論あり)
- DML(MySQL 操作)
が固まっているので、
ここで AST を設計すると OS の命令セットが完全に形式化される。
🧩 DSL パーサ(AST 設計)
ここでは 最小構成で OS として破綻しない AST を設計する。
H2: 1. AST の基本方針
✔ DSL は SQL 風
→ 文法は「1 行 = 1 コマンド」
✔ 型推論あり
→ AST ノードは型を持つが、DSL には書かない
✔ AST は「OS 命令セット」
→ Flask の executor が AST を読み、DB DML を実行する
✔ AST は JSON で表現可能
→ Flask 内部で扱いやすい
H2: 2. AST ノードの種類(MeshOS の命令セット)
あなたの DSL から導かれる AST ノードは以下の 10 種類。
① CreateMeshPrimitive
基本形状(Sphere, Disk, Almond など)
CREATE MESH egg USING SPHERE radius=1 segments=32;
AST:
{
"type": "CreateMeshPrimitive",
"name": "egg",
"primitive": "SPHERE",
"params": { "radius": 1, "segments": 32 }
}
② CreateMeshFromFaces
部分メッシュ生成(extractMeshFromFaces)
CREATE MESH part1 FROM FACES groupA;
AST:
{
"type": "CreateMeshFromFaces",
"name": "part1",
"source_group": "groupA"
}
③ CreateShape
選択領域の形状定義
CREATE SHAPE almond1 USING ALMOND a=1.0 b=0.4 CENTER=(0,0,0);
AST:
{
"type": "CreateShape",
"name": "almond1",
"shape": "ALMOND",
"params": { "a": 1.0, "b": 0.4, "center": [0,0,0] }
}
④ CreatePattern
頂点パターン(RING, GRID など)
CREATE PATTERN r1 USING RING COUNT=10 RADIUS=1 ON PLANE=XY;
AST:
{
"type": "CreatePattern",
"name": "r1",
"pattern": "RING",
"params": { "count": 10, "radius": 1, "plane": "XY" }
}
⑤ CreateVertexGroupFromPattern
CREATE VERTEX_GROUP vg1 FROM PATTERN r1;
AST:
{
"type": "CreateVertexGroupFromPattern",
"name": "vg1",
"pattern": "r1"
}
⑥ SelectFaces
faceIndex 指定 or BFS or SHAPE
SELECT FACES CONNECTED FROM face_id = 120 INTO groupA;
AST:
{
"type": "SelectFaces",
"mode": "CONNECTED",
"from_face": 120,
"into": "groupA"
}
SHAPE 選択なら:
SELECT FACES INSIDE SHAPE almond1 INTO groupB;
AST:
{
"type": "SelectFaces",
"mode": "INSIDE_SHAPE",
"shape": "almond1",
"into": "groupB"
}
⑦ SelectVertices
SELECT VERTICES WHERE DISTANCE_TO (0,0,0) < 0.5 INTO groupC;
AST:
{
"type": "SelectVertices",
"condition": {
"type": "distance",
"center": [0,0,0],
"lt": 0.5
},
"into": "groupC"
}
⑧ Transform (Move / Scale / Rotate)
MOVE groupA BY (0,1,0);
AST:
{
"type": "Transform",
"op": "MOVE",
"target": "groupA",
"value": [0,1,0]
}
⑨ CreateInstance(LinkNode)
CREATE INSTANCE inst1 FROM MESH part1 AT (0,0,0);
AST:
{
"type": "CreateInstance",
"name": "inst1",
"mesh": "part1",
"position": [0,0,0]
}
⑩ Delete
DELETE MESH part1;
AST:
{
"type": "Delete",
"target_type": "MESH",
"target": "part1"
}
H2: 3. AST の構造(1 コマンド = 1 ノード)
DSL は 1 行 1 コマンドなので、
AST は 配列で表現する。
例:
CREATE MESH egg USING SPHERE radius=1 segments=32;
MOVE egg BY (0,1,0);
AST:
[
{
"type": "CreateMeshPrimitive",
"name": "egg",
"primitive": "SPHERE",
"params": { "radius": 1, "segments": 32 }
},
{
"type": "Transform",
"op": "MOVE",
"target": "egg",
"value": [0,1,0]
}
]
H2: 4. パーサの実装方針(Flask 側)
✔ ステップ 1:行ごとにトークン化
- CREATE / SELECT / MOVE / DELETE などのキーワード
- name
- params
- INTO
- FROM
- BY
- AT
✔ ステップ 2:文法に応じて AST ノードを生成
- 正規表現ベースで十分
- SQL パーサほど複雑にしない
✔ ステップ 3:型推論
- groupA → FACE_GROUP
- part1 → MESH
- inst1 → INSTANCE
- vg1 → VERTEX_GROUP
これは AST ノード生成時に自動推論する。
H2: 5. AST → Executor(DB DML)への接続
AST ノードごとに executor を用意する:
| AST.type | Executor |
|---|---|
| CreateMeshPrimitive | create_mesh_primitive() |
| CreateMeshFromFaces | create_mesh_from_faces() |
| CreateShape | create_shape() |
| CreatePattern | create_pattern() |
| CreateVertexGroupFromPattern | create_vertex_group() |
| SelectFaces | select_faces() |
| SelectVertices | select_vertices() |
| Transform | transform() |
| CreateInstance | create_instance() |
| Delete | delete_object() |
これで DSL → AST → DML の OS カーネルが完成する。
🧩 次にやるべきこと(あなたへの提案)
AST が固まったので、次は:
★ ① DSL パーサの実装(Python)
- 正規表現ベース
- AST ノード生成
- 型推論
★ ② Executor の実装
- AST ノードごとに MySQL DML を実行
- combo=i, combo_sub=j を自動付与
★ ③ Three.js 側の DB 読み込み API
/mesh/get/instance/get/group/get
次は DSL パーサの実装(Python コード) に進める?
それとも Executor の設計から行く?