ジェネレーター言語
ジェネレーター言語リファレンス
マッピング設定
マッピング設定は、ジェネレータールール、ラベル宣言、前後処理スクリプトへの参照をマッピングするためのコンテナーです。ジェネレーターモデルには、任意の数のマッピング設定を含めることができます。所有しているジェネレーターモジュールが含まれている場合、それらすべてが生成プロセスに含まれます。マッピング構成は、マッピング優先順位規則で参照できる最小生成単位としても機能します。
ジェネレータールール
ジェネレータールールは、入力ノードから出力ノードへの変換を指定します(入力ノードを持たず、出力モデルに新しいノードを作成するだけの条件付きルートルールを除く)。すべてのルールは、前提と結果の 2 つの部分で構成されます(ルートを放棄するルールは、結果がなく、入力ノードを単に無視する場合を除きます)。ジェネレータールールは、マッピングラベルでタグ付けできます。
すべてのジェネレータールールの機能には、次のパラメーターがあります。
node - 現在の入力ノード ( 条件付きルートルールの条件関数を除くすべて)
genContext - 生成コンテキスト - 出力ノードの検索、一意の名前の生成などが可能
ジェネレータールール
ルール | 説明 | 前提 | 結果 |
---|---|---|---|
条件付きルート規則 | 出力モデルにルートノードを生成します。単一生成ステップ中に 1 回だけ適用されます(最大)。 | 条件関数(オプション)、欠落している条件関数は、常に true を返す関数と同等です。 | ルートテンプレート (参照) |
ルートマッピング規則 | 出力モデルにルートノードを生成します。 |
| ルートテンプレート (参照) |
製織規則 | 追加の子ノードを出力モデルに挿入することを許可します。ウィービング規則は、map_src および参照解決の直前に生成マイクロステップの最後に処理されます。指定した概念の各入力ノードに規則が適用されます。挿入のための親ノードはコンテキスト関数によって提供されるべきです。 |
|
|
削減ルール | このノードが出力モデルにコピーされている間に入力ノードを変換します。 |
|
|
パターンルール | パターンに一致する入力ノードを変換します。 |
|
|
ルートルールを放棄する | それ以外の場合は出力モデルにコピーされる入力ルートノードを削除することを許可します。 |
| なし |
属性ルールの削除 | 変換されたノードの場合、どの属性が入力ノードからコピーされるかを制御します |
| なし ルールが一致しても属性はコピーされません |
ルールの影響
結果 | 使用箇所 | 説明 |
---|---|---|
ルートテンプレート (参照) |
| ルートテンプレートを適用します |
外部テンプレート (参照) |
| 外部テンプレートを適用します。必要に応じてパラメーターを渡す必要があります。パラメーターは次のいずれかになります。
|
weave-each | 製織規則 | 入力ノードのセットに外部テンプレートを適用します。 織り - それぞれの結果は次のもので構成されます:
|
インラインテンプレート |
| ここに書かれているテンプレートコードを適用します。 |
インラインスイッチ | 削減ルール | 条件付きケースのセットとデフォルトのケースで構成されます。 それぞれのケースで結果が指定されます。結果は次のいずれかになります。
|
トップルールを却下 |
| 入力ノードを出力モデルにコピーしようとする試みによって、この一連の変換が開始されるまで、すべての縮小変換を破棄します。入力ノードは「そのまま」コピーされます(他の縮小規則が適用可能でない限り)。ユーザーは、エラー、警告、情報メッセージを指定することもできます。 |
入力を放棄する |
| 入力ノードが出力モデルにコピーされないようにします。 |
ルートテンプレート
ルートテンプレートは、条件付きルートルールおよび(ルート)マッピングルールで使用されます。Generator 言語は、ルートテンプレートの特定の概念を定義していません。ジェネレーター言語は、特別な種類のアノテーション(ルートテンプレートヘッダー)を定義します。これは、新しいルートテンプレートごとに自動的に追加されます。ルートテンプレートヘッダーは、予想される入力の概念(つまり、入力ノードの概念)を指定するために使用されます。MPS はこの設定を使用して、ルートテンプレートで使用されるさまざまなマクロ関数のコードの静的型チェックを実行します。
外部テンプレート
外部テンプレートは、ジェネレーター言語で定義されている概念です。それは製織規則および減少の規則で使用されます。
外部テンプレートでは、ユーザーはテンプレート名、入力概念、パラメーター、およびコンテンツノードを指定します。
コンテンツノードは、出力言語の任意のノードにすることができます。外部テンプレートの実際のテンプレートコードは、テンプレートフラグメントの「タグ」で囲まれています(テンプレートフラグメントも特別な種類のアノテーションの概念です)。テンプレートフラグメントの外側のコードは、実際のテンプレートコード(テンプレートフラグメント)のフレームワーク(またはコンテキスト)として機能し、ジェネレーターによって無視されます。ルールを織り込むための外部テンプレートでは、テンプレートのコンテキストノードが必要です(これはルールのコンテキストノードの設計時の表現です)が、削減ルールのテンプレートは 1 つのコンテキストフリーテンプレートフラグメントにすることができます。リダクションルールの外部テンプレートには、テンプレートフラグメントが 1 つだけ含まれている必要がありますが、ウィービングルールのテンプレートには複数のテンプレートフラグメントを含めることができます。
テンプレートフラグメントにはインスペクタビューで編集されるマッピングラベルプロパティがあります。
マッピングラベル
マッピングラベルはマッピング設定で宣言され、この宣言に格納された参照はジェネレータールール、マクロ、テンプレートフラグメントのラベル付けに使用されます。そのようなマークは、既知の入力ノードによる出力ノードの発見を可能にします。
Properties:
名前
入力概念(オプション) - タグ付きルール、マクロ、テンプレートフラグメントによって実行される変換の入力ノードの想定される概念
出力コンセプト(オプション) - タグ付きルール、マクロ、テンプレートフラグメントによって実行される変換の出力ノードの想定されるコンセプト
MPS は、入出力の概念設定を利用して、get output ... 操作で静的型チェックを実行します。
マクロ
マクロは、テンプレートコード内の任意のノードにアタッチできる特別な種類のアノテーション概念です。マクロは、動的な側面を他の点では静的なテンプレートベースのモデル変換に取り入れます。
プロパティマクロと参照マクロはそれぞれプロパティセルと参照セルに割り当てられ、ノードマクロ(LOOP、IF など)はセルエディターのノード全体を表すセルに割り当てられます。マクロのすべてのプロパティは、インスペクタビューを使って編集します。
すべてのマクロには、マッピングラベルプロパティ(マッピングラベル宣言への参照)があります。さらに、マクロの種類に応じて、すべてのマクロをさまざまなマクロ関数でパラメーター化することができます。どのマクロ関数にも、少なくとも以下の 3 つのパラメーターがあります。
node - 現在の入力ノード
genContext - 生成コンテキスト - 出力ノードの検索、一意の名前の生成などができます。
operationContext - jetbrains.mps.smodel.IOperationContext インターフェースのインスタンス(めったに使用されません)。
多くの種類のマクロには、マップされたノード(またはマップされたノード)機能があります。この関数は、新しい入力ノード(現在の入力ノードの代わり)を計算します。マップされたノード関数が null を返すか、マップされたノード関数が空のシーケンスを返す場合、ジェネレーターはこのマクロを完全にスキップします。つまり、この場所では出力は生成されません。
マクロ | 説明 | Properties (上記以外の場合) |
---|---|---|
プロパティマクロ | プロパティの値を計算します。 | 値の機能:
|
参照マクロ | 出力モデルの指示対象ノードを計算します。 通常、出力モデル(ツリー)がすでに構築されている場合、生成マイクロステップの最後に実行されます。 ユーザーコードが参照のターゲットを取得しようとしている場合は、以前に実行することもできます。 参照マクロは、新しいターゲットの指定として | 参照関数
|
IF | ラップされたテンプレートコードは、条件が真の場合にのみ適用されます。それ以外の場合、テンプレートコードは無視され、「代替の結果」(ある場合)が適用されます。 | 条件関数 > 代替結果(オプション)- 次のいずれか:
|
LOOP | 新しい入力ノードを計算し、ラップされたテンプレートを各ノードに適用します。また、LOOP マクロによってラップされたノードに接続されているマクロのクエリで使用できるようになる LOOP 変数も導入されています。LOOP 変数は、LOOP マクロによって現在処理されているノードへのアクセスを提供します。例: | マップノード機能 |
INCLUDE | ラップされたテンプレートコードは無視され(INCLUDE マクロのアンカーとしてのみ機能します)、代わりに再利用可能な外部テンプレートが使用されます。 NULL 入力は INCLUDE を実質的に何もしません。 |
|
CALL | テンプレートを呼び出し、ラップされたテンプレートコードをテンプレート呼び出しの結果で置き換えます。パラメーター付きのテンプレートをサポートします。 この場合、null 入力ノードは許容され、テンプレートは完全に無視されます。すなわち、入力/マッピングされたノードが null のとき、結果として CALL は空のノードの集合を生成します。 |
|
SWITCH | テンプレートコードの特定の場所で多くの代替変換を行う方法を提供します。 どの switch case も適用できず、# テンプレートスイッチでデフォルトの結果が指定されていない場合は、ラップされたテンプレートコードが適用されます。 入力ノードが NULL の場合、SWITCH はメッセージ(その規則に従って指定されたもの)と反応し、アンカーテンプレートノードは無視され、SWITCH マクロは結果を生成しません。 |
|
CALL-SITE | 呼び出されたテンプレートの指定された場所に、SWITCH/CALL マクロに起因するノードの挿入を容易にします。SWITCH/CALL マクロでラップされたノードが呼び出されたテンプレート / スイッチに関連しているシナリオでは、このマクロはそれを「呼び出しサイトノード」としてアタッチします。このような場合、ノードは通常のテンプレート(潜在的なマクロを含む)として処理され、結果は暗黙の引数として呼び出されたテンプレート / スイッチに提供され、目的の場所に挿入できるようになります。 テンプレートとスイッチ宣言には、呼び出しサイトノードを使用することを示すフラグ (インテンションによって切り替えられる) があります。呼び出しサイトを取得する必要があることを示していないテンプレート / スイッチ内で $CALL-SITE$ マクロを使用するとエラーになります。CALL/SWITCH で明示的な引数を指定する必要はありません。MPS ジェネレーターは、テンプレート / スイッチにその呼び出しサイトが必要であることを認識し、そのような場合、それを処理する前にさらにテンプレート (マクロを含む) を評価します。この機能は、条件付き型キャスト
| |
COPY-SRC | 入力ノードを出力モデルにコピーします。ラップされたテンプレートコードは無視されます。 | マップされたノード関数 - コピーされる入力ノードを計算します。 |
COPY-SRCL | 入力ノードを出力モデルにコピーします。ラップされたテンプレートコードは無視されます。 複数の集約カーディナリティを持つ子供にのみ使用できます。 | マップノード関数 - コピーする入力ノードを計算します。 |
MAP-SRC | 多機能マクロは、のために使用することができます。
|
|
MAP-SRCL | MAP-SRC と同じですが、多くの新しい入力ノードを処理できます (LOOP マクロに似ています) |
|
WEAVE | 製織ルールが使用されるのと同様の方法で、追加の子ノードを出力モデルに挿入することを許可します。WEAVE マクロでラップされた(または use input 関数によって提供された)ノードには、提供されたテンプレートが適用され、生成されたノードが挿入されます。 | use input マクロを適用するノードのコレクションを返す関数 weave 入力として提供されたノードに織り込むためのテンプレートへの参照 |
VAR | 1 つ以上の名前付き値をジェネレーターコンテキストに導入します。ジェネレーターコンテキストは、genContext オブジェクトから取得できます。格納された変数は読み取り専用であり、VAR マクロのスコープ内のジェネレーターコンテキストに存在します。 | 各変数には次のパラメーターがあります。
|
テンプレートスイッチ
テンプレートスイッチは、SWITCH マクロ(TemplateSwitchMacro の概念)と組み合わせて使用されます。単一のテンプレートスイッチは、さまざまな SWITCH マクロで再利用できます。テンプレートスイッチは、一連のケースと 1 つのデフォルトケースで構成されます。各 switch case は削減ルールです。つまり、テンプレートスイッチには削減ルールのリストが含まれています。
デフォルトのケースの結果は、次のいずれかになります。
外部テンプレート (参照)
インラインテンプレート
入力を放棄する
トップルールを却下
.. または省略できます。この場合、対応する SWITCH マクロで囲まれたテンプレートコードが適用されます。
テンプレートスイッチは、extends プロパティを介して他のスイッチから削減ルールを継承できます。ジェネレーターが SWITCH マクロを実行しているとき、最も特定のテンプレートスイッチ(スコープ内で利用可能)を見つけようとします。実際に実行されたテンプレートスイッチは、SWITCH マクロのテンプレートスイッチプロパティで定義されているものとは限りません。
null 入力メッセージプロパティにより、ユーザーはエラー、警告または info メッセージを指定できます。これは、SWITCH-macro のマップされたノード関数が null を返す場合に表示される MPS メッセージビューに表示されます(デフォルトではメッセージは表示されず、マクロは完全にスキップされます)。
テンプレートスイッチは、テンプレート宣言と同じ方法でパラメーターを受け取ることができます。パラメーター化されたスイッチを使用すると、SWITCH マクロで引数を指定する必要があります。TemplateSwitchMacro
の概念は、引数ありと引数なしの両方でスイッチをサポートします。
生成コンテキスト (操作)
生成コンテキスト(マクロ関数およびルール関数の genContext パラメーター)を使用すると、出力モデル内のノードを検索したり、一意の名前を生成したり、その他の便利な機能を提供したりできます。
生成コンテキストはジェネレーターモデルだけでなくユーティリティモデルでも gencontext 型の変数として使用できます。
genContext の操作は、おなじみのドット表記 genContext.operation を使用して呼び出されます。
出力ノードの検索
モデルの出力 <mapping label> を取得します ( <モデル> ) | 指定されたモデルのラベル付き条件付きルートルールによって生成された出力ノードを返します。 一致する出力ノードが複数ある場合、エラーを発行します。 |
---|---|
<マッピングラベル> の出力を取得 ( <input node> ) | ラベル付きジェネレータールール、マクロ、テンプレートフラグメントによって入力ノードから生成された出力ノードを返します。 一致する出力ノードが複数ある場合、エラーを発行します。 |
出力 <mapping label> を選択 ( <input node> ) | 参照マクロ内の指示対象関数のコンテキストでのみ使用され、必要な出力ノードが参照のターゲットであり、その参照マクロによって解決されている場合にのみ使用されます。 ラベル付きジェネレータールール、マクロ、テンプレートフラグメントによって入力ノードから生成された出力ノードを返します。この操作と前の操作の違いは、この操作は多くの出力ノードの競合を自動的に解決できることです。つまり、指定されたコンテキストで表示される出力ノードを選択します。 |
出力リスト <mapping label> の取得 ( <input node> ) | ラベル付きジェネレータールール、マクロ、テンプレートフラグメントによって入力ノードから生成された出力ノードのリストを返します。 |
コピー出力を取得 ( <input node> ) | 入力ノードのコピーによって作成された出力ノードを返します。コピー中に入力ノードが縮小されたが、出力ノードの概念が同じである場合(つまり、まったく異なるものに縮小されていない場合)、これは「コピー」と見なされます。 一致する出力ノードが複数ある場合、エラーを発行します。 |
一意の名前を生成する
からの固有の名前 <base name> 文脈で <node>
独自性は、世代セッション全体を通じて確保されます。
このサービスを使用して生成されなかった名前との衝突は引き続き発生する可能性があります。
コンテキストノードはオプションですが、生成の安定性を保証するために指定することをお勧めします。指定した場合、MPS はスコープ(通常はルートノード)に「含まれる」名前を生成するように最善を尽くします。(入力モデルやジェネレーターモデルの変更により)名前が再計算されても、範囲外の他の名前には影響しません。
テンプレートパラメーター
#patternvar | キャプチャーされたパターン変数の値 ルールの結果でのみ利用可能 |
---|---|
param | テンプレートパラメーターの値 外部テンプレートでのみ使用可能 |
コンテキスト情報の取得
inputModel | 現在の入力モデル |
---|---|
originalModel | 元の入力モデル |
outputModel | 現在の出力モデル |
templateNode | マクロで囲まれたテンプレートコード。 マクロ関数でのみ使用されます 主な欠陥は、この操作が解釈されたテンプレートを意味するということです。テンプレートが生成されるときにテンプレートモデルはありません。 その上、操作の契約はあいまいです(たとえば、テンプレート呼び出しのための引数照会の文脈で何をしますか)。 |
前の入力を取得 <マッピングラベル> | ラベル付きマクロで囲まれたテンプレートコードを囲むために使用された入力ノードを返します。 マクロ関数でのみ使用されます。 |
ユーザーデータの転送
生成中、MPS はユーザーオブジェクトの 3 つのマップを管理します。それぞれのマップは異なる寿命を持ちます。
セッションオブジェクト - 生成セッション全体を通して保持されます。
ステップオブジェクト - 単一の生成ステップを通じて保持されます。
一時的なオブジェクト - マイクロステップの間だけ生きています。
開発者は、配列(角括弧)表記を使用してユーザーオブジェクトマップにアクセスできます。
キーは任意のオブジェクト(java.lang.Object)にすることができます。
ロギング
MPS メッセージビューにメッセージを作成します。ノードパラメーターが指定されている場合、メッセージをクリックするとそのノードに移動します。エラーメッセージが表示された場合、MPS は追加の診断情報も出力します。
ユーティリティ (再利用可能なコード)
(ルール、マクロなどで)コードが重複していて、それを再利用可能な静的メソッドに抽出したい場合は、このクラスを別の非ジェネレーターモデルで作成する必要があります。
ジェネレーターモデル(つまり「ジェネレーター」ステレオタイプを持つモデル)でユーティリティクラスを作成すると、ルートテンプレート(未使用)として扱われ、そこからコードは生成されません。
マッピングスクリプト
マッピングスクリプトはユーザーコードであり、モデル変換の前(前処理スクリプト)または後に(後処理スクリプト)実行されます。生成ステップの一部として呼び出されるように、# マッピング設定から参照する必要があります。マッピングスクリプトは、非テンプレートベースのモデル変換を実行する機能を提供します。
前処理スクリプトは、入力モデルから特定の情報を収集するためにも一般的に使用されています。これは、後でテンプレートベースの変換の過程で使用できます。スクリプトによって収集された情報は、一時オブジェクト、ステップオブジェクト、セッションオブジェクトとして保存されます。
スクリプトサンプル:
Properties:
スクリプトの種類 |
|
---|---|
モデルを変更します | スクリプトの種類 = 前処理入力モデルの場合にのみ使用可能 true に設定され、入力モデルが元の入力モデルである場合、MPS はスクリプトを適用する前にそれを一時的な入力モデルに複製します。その後、スクリプトは自由にモデルを変更できます。スクリプトによって行われた変更は、コード生成の次のフェーズで表示されます。 false に設定すると、入力モデルは複製されず、スクリプトはモデルを変更できません。スクリプトが入力モデル MPS を変更しようとすると、エラーが発生します。 |
コードの内容
モデル | 現在のモデル |
---|---|
genContext | 一時オブジェクト / セッションオブジェクトまたはステップオブジェクトへのアクセス権を付与するための生成コンテキスト。 |
ジェネレーターのパフォーマンスに関するヒント
MPS チームはジェネレーターの高速化に力を入れています。ただし、プロジェクトのサイズが大きくなり、特にモデル内のルートノードの数が増えると、生成時間が問題になる状況が発生する可能性があります。この章では、ジェネレーター定義をリファクタリングしてジェネレーターのパフォーマンスを向上させる方法に関するヒントをいくつか紹介します。
モデル生成パフォーマンスレポート機能を使用する - MPS 設定ダイアログを使用すると、ジェネレーターによる詳細なパフォーマンスレポートの作成を有効にすることができます。レポートでは、最も時間のかかるジェネレーターのステップが最初に並べられます。時間のかかるジェネレーターステップと単一ステップ内のアクティビティを簡単に特定できます。
コードをランタイムに移動する - 生成する必要があるのは、ジェネレーターテンプレート内のコードのみです。テンプレートから抽出して言語のランタイムに移動するコードが増えるほど、ジェネレーターのパフォーマンスが向上します。理想的には、入力モデルに基づいて変更されるコードのみがテンプレートに属します。
動的参照の使用を避ける - 参照マクロは、node/node-ptr または文字列値を返す場合があります。文字列値は未解決の参照 (MPS ジェネレーターでは動的参照と呼ばれます) を表し、ジェネレーターは各生成ステップでその参照を解決しようとします。これにより、モデル生成パフォーマンスレポートの参照の復元セクションに費やされる時間から簡単にわかるように、生成プロセスが大幅に遅くなります。
可能であれば、代わりに戻り値の型として、node/node-ptr を使用してください。あるいは、参照の代わりに文字列プロパティを保持する単一目的の概念を生成し、BaseLanguage の生成時に参照を表すために Jetbrains.mps.baseLanguageInternal が使用されるのと同様の方法で、動的参照の代わりに使用することもできます。
ジェネレーターでの型計算を避ける - Jetbrains.mps.lang.typesystem 言語は、ジェネレーター内の任意のノードのタイプを決定するための .type 操作を提供します。ただし、この操作は非常に時間がかかるため、ジェネレーター内で繰り返し使用することは避けることをお勧めします。代わりに、型を一度計算して、後で使用するためにジェネレーターコンテキストの一時オブジェクトに保存することもできます。
ジェネレーターの性能調査では、これらのヒントの背後にあるさらなる理論的根拠を見つけることができます。
関連ページ:
パターン
パターン言語:パターン言語には、モデル構造のパターンを定義するという単一の目的があります。これらのパターンは、マッチングしたいノードの視覚的表現を形成します。ノードのプロパティ値がパターンで指定された値と等しい場合、パターンはノードと一致し、ノードの参照はパターンのものと同じターゲットを指し、対応する子はパターンの適切な子と一致します。また、パターンにはノード、参照、プロパティの変数を含めることができます。これらの変数は、任意のノード / 参照 / プロパティに一致します。それに加えて、変数は...
ジェネレーターのパフォーマンスを向上させるためのヒント
MPS ジェネレーターを高速化し、400% によってビルド速度を向上させる:Daniel Stiegler (Modellwerkstatt) と V á clav Pech 著 (JetBrains)Daniel Stieger は、Java ローコードプラットフォーム MoWare Werkbank を提供するオーストリアの企業、modellwerkstatt.org のパートナーです。このプラットフォームは、ビジネスアプリケーション、つまり特定の企業の特定のビジネスプロセスをサポートする...
生成プログラム
導入:ジェネレーターは、言語の概念の表示的意味論を定義する言語仕様の一部です。MPS はモデル間変換アプローチに従います。MPS ジェネレーターは、入力言語でエンコードされた構成から出力言語でエンコードされた構成への変換を指定します。モデル間変換のプロセスには多くの中間モデルが含まれ、最終的には sn 出力モデルが生成されます。このモデルでは、すべての構成はすでに意味が別の場所で定義されている言語になります。たとえば、baseLanguage のほとんどの概念 (クラス、メソッドなど) は「機械が...
ジェネレーターアルゴリズム
ジェネレーターアルゴリズム:入力モデルからターゲットアセットを生成するプロセス(生成セッション)には、5 つのステージが含まれます。関与する必要があるすべてのジェネレーターの定義、変換の優先順位を定義する、段階的なモデル変換、テキストを生成してファイルに保存する (出力モデルの各ルートに対して)、後処理アセット: コンパイルなど、このプロセスの最初の 3 段階について詳しく説明します。関与するジェネレーターの定義必要なジェネレーターを定義するために、MPS は入力モデルを調べて、その中で使用さ...