MPS 2020.1 ヘルプ

生成プログラム

導入

Generator は、言語仕様の一部であり、言語の概念の表示(英語)セマンティクスを定義します。

MPS はモデル間変換アプローチに従います。MPS ジェネレーターは、入力言語でエンコードされた構成から出力言語でエンコードされた構成への変換を指定します。モデル間変換のプロセスには多くの中間モデルが含まれ、最終的には sn 出力モデルが生成されます。このモデルでは、すべての構成はすでに意味が別の場所で定義されている言語になります。

たとえば、baseLanguage のほとんどの概念(クラス、メソッドなど)は「マシンで理解可能」であるため、baseLanguage が出力言語としてよく使用されます。

ターゲットアセットは、出力言語でサポートされている必要があるモデルからテキストへの変換を適用して作成されます。モデルからテキストへの変換を定義するための言語の側面TextGen と呼ばれ、コンセプトのエディターの別のタブとして利用できます。MPS は生成されたアセットの破壊的な更新のみを提供します。

たとえば、baseLanguageTextGen アスペクトは次の場所に *.java ファイルを生成します。
< ジェネレーター出力パス > \ < モデル名 > \ <ClassName> .java
ここで、
ジェネレーター出力パス - 入力モデルを所有するモジュールで指定されています。
モデル名 - 「.」を置き換えることによって作成されたパスセグメントです。入力モデルの名前にはファイル区切り文字を使用します。

概要

ジェネレーターモジュール

他の言語の側面とは異なり、ジェネレーターの側面は単一のモデルではありません。ジェネレーター仕様は、実用新案だけでなく多くのジェネレーターモデルを含むことができます。ジェネレーターモデルには、テンプレートマッピング構成、およびその他のジェネレーター言語の構成が含まれています

ジェネレーターモデルは、モデルステレオタイプ - ' generator '(モデル名の後に < name > @ generator と表示されています)によって通常のモデルと区別されます。
下のスクリーンショットは、例として smodel 言語のジェネレーターモジュールを示しています。

gug generator module

新しいジェネレーターを作成する

言語のポップアップメニューの新規 -> ジェネレーターコマンドを使用して新しいジェネレーターが作成されます。

1 つの言語に対して複数のジェネレーターを作成することは可能です。言語に単一のジェネレーターがある場合、その言語を使用することは、そのジェネレーターを使用してモデルのコードを生成することを意味します。ただし、複数のジェネレーターで言語を使用する場合、ユーザーはトリガーするジェネレーターを選択するために追加の手順が必要です。現在、これはジェネレーター計画を通じて行われています。

新しいジェネレーターモジュールを作成するとき、MPS は空のマッピング設定ノードを含むジェネレーターモデル 'main @ generator' も作成します。

ジェネレーターのプロパティ

モジュールとして、generator は他のモジュールに依存したり、言語使ったり、devkits使ったりしましたモジュールメタ情報を参照)。

ジェネレーターのプロパティダイアログには、2 つの追加プロパティがあります。

  • ジェネレーターに依存 - 他のジェネレーターへの依存関係を指定します。これにより、従属ジェネレーターは別のジェネレーターで定義されたテンプレートを参照することができます。

  • マッピング制約 - マッピング規則間の優先順位関係を指定できます。そのような関係が他のジェネレータールールを含む場合、そのジェネレーターへの依存関係を宣言することも必要です。

ジェネレーター

MPS ジェネレーターエンジン(またはジェネレーター言語ランタイム)は変換の実行に混合コンパイル / 解釈モードを使用します。

テンプレートは実行時に解釈および入力されますが、ルール、マクロ、スクリプト内のすべての関数は事前にコンパイルされている必要があります。

混乱を避けるために、必ずこの規則に従ってください。ジェネレーターモデルを変更した後は、モデルを再生成する必要があります(Shift+F9)。Ctrl+F9 を使用することをお勧めします。これにより、ジェネレーターモジュール内のすべての修正モデルが再生成されます。

変換

変換はテンプレートによって記述されます。テンプレートは出力言語を使って書かれているため、通常その言語で ' 通常のコード ' を書くのに使われるのと同じセルエディターで編集することができます。追加の労力なしで、「テンプレートエディター」は、構文 / エラーのハイライト、自動補完など、すぐに同じレベルのツーリングをサポートします。テンプレートは、入力モデルを参照することによってパラメーター化されます。

個々のテンプレートの適用性は # ジェネレータールールによって定義され、それらは # マッピング設定に分類されます。

マッピング設定

マッピング設定は最小単位で、単一の生成ステップを形成できます。これは # ジェネレータールールを含み、マッピングラベルを定義し、プレ後処理スクリプトを含みます。

ジェネレータールール

各変換の適用可能性は生成規則によって定義されます。
ジェネレータールールには 6 種類あります。

  • 条件付きルート規則

  • ルートマッピング規則

  • 製織規則

  • 削減ルール

  • パターンルール

  • ルートルールを放棄する

  • 属性ルールの削除 ( 3.3 の新機能 )

各ジェネレータールールは、前提結果から構成されます(ユーザが指定できない事前定義済みの結果を伴う、破棄ルートルールドロップ属性ルールを除く)。

条件付きルート規則を除くすべての規則には、その前提内に入力ノードの概念(または単に入力概念)への参照が含まれています。すべてのルール前提には、オプションの条件関数も含まれています。

ルール結果には通常、外部テンプレート(つまり、同じモデルまたは異なるモデルでルートノードとして宣言されたテンプレート)への参照、またはいわゆるインラインテンプレート(条件付きルートルールおよびルートマッピングルールは外部テンプレートへの参照しか持てません)が含まれます。結果には他にもいくつかのバージョンがあります。

次のスクリーンショットは、ジェネレーターモデルの内容とマッピング設定の例を示しています。

gug mapping configuration

マクロ

テンプレート内のコードはマクロを通してパラメーター化することができます。ジェネレーター言語は 3 種類のマクロを定義します。

  • プロパティマクロ - プロパティ値を計算します。

  • 参照マクロ - 参照のターゲット(ノード)を計算します。

  • ノードマクロ - 生成時にテンプレートの埋め込みを制御するために使用されます。ノードマクロにはいくつかのバージョンがあります - LOOP マクロはその一例です。

マクロは特別な種類のいわゆる注釈概念を実装しており、テンプレートコード内で(マクロの種類に応じて)プロパティセル、参照セル、またはノードセルをラップできます。

コードの折り返し(つまり、新しいマクロの作成)は、Ctrl+Shift+M を押すか、または 'Create macro' インテンションを適用することによって行われます。

次のスクリーンショットは、プロパティマクロの例を示しています。

gug property macro sample

マクロ機能やその他のパラメーター設定オプションは、インスペクタビューで編集します。たとえば、プロパティマクロでは、生成時にプロパティの値を提供する value 関数を指定する必要があります。上記の例では、出力クラスノードは、入力ノードと同じ名前になります

ジェネレーター言語のすべての関数のノードパラメーターは常に、変換が現在適用されているコンテキストノード(入力ノード)を表します

いくつかのマクロ(LOOP および SWITCH マクロなど)は入力ノードを新しいものと置き換えることができるため、後続のテンプレートコード(たとえばそれらのマクロによってラップされるコード)は新しい入力ノードに適用されることになる。

外部テンプレート

外部テンプレートは、ジェネレーターモデルのルートノードとして作成されます。

MPS には 2 種類の外部テンプレートがあります。

その 1 つがルートテンプレートです。ジェネレーターモデルで作成されたルートノードは、このノードがジェネレーター言語の一部でない限り、ルートテンプレートとして扱われます(つまり、マッピング設定はルートテンプレートではありません)。ルートテンプレートは通常のルートノードとして作成されます(モデルのポップアップのルートノードを作成するメニューを介して)。

次のスクリーンショットは、ルートテンプレートの例を示しています。

gug root template sample

このルートテンプレートは入力ノード(文書)をクラスbaseLanguage)に変換します。ルートテンプレートヘッダは作成時に自動的に追加されますが、入力ノードの概念はユーザによって指定されます。

MPS はマクロ関数のコード内で静的型チェックを実行できるため、入力の概念を指定することをお勧めします。

ルートテンプレート(参照)は、条件付きルート規則およびルートマッピング規則の結果として使用できます。(条件付きルートルールで使用されている場合、入力ノードは利用できません)。

2 番目の種類のテンプレートはジェネレーター言語で定義されており、その概念名は 'TemplateDeclaration' です。それはルートノードを作成するメニューの ' テンプレート宣言 ' アクションを通して作成されます。

gug new template declaration menu

次のスクリーンショットはテンプレート宣言の例を示しています。

gug template declaration sample

実際のテンプレートコードはテンプレートフラグメントに 「ラップ」されています。テンプレートフラグメントの外側のコードは変換に使用されず、コンテキストとして機能します(たとえば、Java クラスを持つことはできますが、そのメソッドの 1 つだけをテンプレートとしてエクスポートできます)。

テンプレート宣言はヘッダで宣言されたパラメーターを持つことができます。パラメーターは #generation コンテキストを通してアクセス可能です。

テンプレート宣言は編むこと、減少およびパターン規則の結果として使用されます。これは INCLUDE-macro に含まれるテンプレートとして(パラメーターのないテンプレートに対してのみ)、あるいは CALL-macro の呼び出し先としても使われます。

テンプレートスイッチ

テンプレートスイッチは、テンプレートコードの特定の場所で 2 つ以上の代替変換が可能な場合に使用されます。その場合、選択肢を許可するテンプレートコードは、SWITCH マクロにラップされています。これはテンプレートスイッチを参照しています。Template Switch はルートノードを作成するメニューを介してジェネレーターモデルのルートノードとして作成されます(このコマンドは上の 'menu' スクリーンショットで見ることができます)。

次のスクリーンショットは、テンプレート切り替えの例を示しています。

gug template switch sample

Ant から生成する

Ant MPS ジェネレータータスクは、ビルドスクリプトから設定可能なプロパティ(パラレル、スレッド、インプレース、警告)を公開します。ビルド言語は、ビルドプロセス中にモデルを変換するために、Ant Generate タスクを使用します。このタスクは今ジェネレーター設定ページからおなじみのパラメーターを公開します:

  • 厳格生成モード
  • 構成可能な数のスレッドによる並列生成
  • インプレース変換を有効にするオプション
  • 生成警告 / エラーを制御するオプション

これらのオプションは BuildMps_GeneratorOptions の概念を使用してビルド言語でも公開されているため、ビルドスクリプトでプロセスをより細かく制御できます。

サンプル

さらに実用的な経験が必要なときは、ジェネレーターデモをチェックしてください。
デモには、上記のすべての概念の使用例が含まれています。

関連ページ:

ジェネレータークックブック

この文書は、MPS ジェネレータに関する最も一般的な質問に対する回答を提供することを目的としています。代わりにジェネレータのドキュメントを調べてジェネレーターデモをチェックすることもできます。ジェネレータはどのようにルールを処理しますか?、一つの言語に対してさらに多くのジェネレータを使うことができま...

TextGen

TextGen 言語アスペクト :導入TextGen言語アスペクトは、テキスト変換へのモデルを定義します。モデルを直接テキスト形式に変換する必要があるたびに便利です。この言語には、テキストを出力し、ノードをテキスト値に変換し、出力に合理的なレイアウトを与えるための構成要素が含まれています。操作app...

SModel 言語

SModel 言語の目的は、MPS モデルを照会および変更することです。これにより、モデルのノード、属性、プロパティ、リンク、他の多くの本質的な品質を調査できます。言語は、言語のいくつかの異なる側面(アクション、リファクタリング、ジェネレーター)をエンコードして、最も目立つものに名前を付ける必要があ...

世代計画

世代計画 :生成計画を使用すると、開発者は自分のモデルに望ましい生成順序を明示的に指定でき、生成プロセスをより適切に制御できます。目的大規模プロジェクトでは、相互ジェネレーターの優先順位を指定するのが面倒になるかもしれません。さらに、優先順位を指定するためには、適切な相互依存関係を宣言することによっ...

ジェネレーターデモ

ジェネレーターチュートリアル :更新された Generator Tutorial へようこそ。MPS で言語生成プログラムを定義および拡張する手順を案内します。チュートリアルは 7 つの部分から成り、徐々に複雑さが増しています。すべてのデモは同じ基本的な物語 -Java Swing コンポーネントへ...

データフロー

言語のデータフローの側面では、到達不能なステートメントの検索、未使用の代入の検出、変数が読み込まれる前に初期化されていない可能性があるかどうかの確認などを行うことができます。また、「抽出メソッド」リファクタリングなど、いくつかのコード変換を実行することもできます。データフロー分析のほとんどのユーザー...