構造
MPS を使用すると、目的の言語の文法を定義する必要がなくなるため、言語の構造を指定するためのさまざまな方法が明らかに必要になります。ここで構造言語が役に立ちます。それはあなたに言語構造を定義するためのすべての手段を与えます。前に説明したように、MPS でコーディングする場合、AST を直接効果的に構築しているため、言語の構造では、AST の構築に使用する要素であるブリックを指定する必要があります。
プロパティ、参照、および子供 : レンガをコンセプトと構造言語が公開の概念と概念インターフェースだけでなく、そのメンバーと呼ばれています。
概念と概念インターフェース
それでは、さらに詳しく見てみましょう。コンセプトは、言語を使用して記述されたコードを表す将来の AST のノードであるコンセプトインスタンスの構造を定義します。コンセプトには、ノードにどのプロパティが含まれるか、どのノードが参照されるか、どの子ノードが許可されるかが記載されています (ノードの詳細については、基本的な考え方セクションを参照してください)。
コンセプトとは別に、コンセプトインターフェースもあります。概念インターフェースは、多くの異なる概念によって継承および実装できる独立したトレイトを表します。通常、これらを使用して、直交する概念を 1 つの概念にまとめます。例: あなたのコンセプトのインスタンスは、それが識別できる名前を持っている場合、あなたのコンセプトに INamedConcept インターフェースを実装することができますし、name プロパティに加えて、あなたのコンセプトに追加し、関連する行動と制約を取得します。
概念の継承
オブジェクト指向プログラミングの場合と同様に、コンセプトは別のコンセプトを拡張し、多くのコンセプトインターフェースを実装できます。コンセプトインターフェースは、他の複数のコンセプトインターフェースを拡張できます。このシステムは Java クラスに似ており、クラスは 1 つのスーパークラスしか持つことができませんが、多くの実装されたインターフェースを持ち、インターフェースは他の多くのインターフェースを拡張できます。
ある概念が別の概念を拡張したり概念インターフェースを実装したりすると、他動詞的にすべてのメンバーを継承します。(つまり、A がメンバー m を持ち、A が B によって拡張され、B が C によって拡張される場合、C もメンバー m を持ちます。)
特別な意味を持つ概念インターフェース
MPS には、概念によって実装されたときに特別な意味または動作を持つ概念インターフェースがいくつかあります。これは最も有用なもののリストです:
コンセプトインターフェース | 意味 |
---|---|
IDeprecatable | コンセプトのインスタンスが非推奨になる可能性がある場合に使用されます。isDeprecated 動作メソッドは、ノードが非推奨であるかどうかを示します。ターゲットの isDeprecated が true を返す場合、エディターは参照セルの取り消し線スタイルを設定します。 |
INamedConcept | コンセプトのインスタンスに識別名がある場合に使用されます。デフォルトでは、この名前は、参照用のコード補完リスト内の可能なターゲットとしてノードを表します。さらに、プロジェクトビューに名前が表示されます。 |
INamedValidIdentifier | コンセプトのインスタンスに識別名がある場合に使用されます。インターフェースは INamedConcept を拡張し、名前として使用される有効な Java 識別子を保証する制約を追加します。BaseLanguage に属し、BaseLanguage 拡張機能でのみ使用する必要があります。 |
INamedAspect | 言語定義のある側面の一部である名前付き概念に使用されます。インターフェースは、有効な Java 識別子が使用されることを保証します。 |
タイプする | 型を表すすべての概念をマークするために使用されます |
I ラッパー | 直接の親が IWrapper のインスタンスであるノードを削除すると、親ノードも削除されます。 |
コンセプトメンバー
Properties
プロパティは、コンセプトインスタンス内に格納されている値です。各プロパティにはタイプが必要です。タイプは、プロパティの場合、次のように制限されます。ブール値、文字列、整数などのプリミティブ。 列挙型。事前定義されたセットの値を持つことができます。制約付きデータ型(正規表現によって制約された文字列)。コンセプトの制約のプロパティに getter と setter を定義できます。
リファレンス
スカラー値を保持することは、それほど遠くはありません。言語の表現力を高めるために、ノードは他のノードへの参照を格納できます。各参照には、名前、タイプ、およびカーディナリティがあります。タイプは、参照ターゲットの許可されるタイプを制限します。カーディナリティは、ノードが持つことができるこの種の参照の数を定義します。参照には、1:0..1 および 1:1 の 2 種類のカーディナリティのみを含めることができます。
参照のために逆方向に横断する直接的な方法はありません。そのためには、jetbrains.mps.lang.findUsages
言語と execute finder
を使用する必要があります。(これらは生成中は確実には機能しません)。
スマートリファレンス
1:1 カーディナリティの単一参照を含み、エイリアスが定義されていないノードは、スマート参照と呼ばれます。これらはやや特殊なリファレンスです。言語の作成者がエイリアスを指定していない場合、言語のユーザーから隠蔽し、可能な限り透明になるよう最善を尽くします。MPS はノードを実際の参照そのものであるかのように扱い、コード編集とコード補完を簡素化します。例: デフォルトの補完項目は、補完メニューが必要な場合に常に作成されます。考えられる参照ターゲットごとに、ターゲットノードのプレゼンテーションと一致するテキストを使用してメニュー項目が作成されます。
自動的にスマートとして扱われるための上記の基準を満たさない参照をスマートにするには、コンセプト宣言に @smart 参照属性でアノテーションを付ける必要があります。典型的な使用例は、プレゼンテーションをカスタマイズするコンセプトです。参照の追加、または追加の参照を保持します。
子
ノードを木に組み立てるために、子供たちがそれらにつながれることを可能にする必要があります。各子宣言は、ゴール概念、そのロールおよび濃度を保持します。ターゲットコンセプトは子供の種類を指定します。ロールは、この子グループの名前を指定します。最後に、カーディナリティは、このグループの子を 1 つのノードに含めることができる数を指定します。1:1、1:0..1、1:0..n、1:1..n の 4 種類のカーディナリティがあります。
プログラム的に、node.children は現在のノードの子であるすべてのノードを取得します。node.children の逆は node.parent または node.ancestor(s) です。
特別な参考文献と子供
ある概念が別の概念を拡張するときに、そのすべてのメンバーを継承するだけでなく、そのトレイトの一部をオーバーライドしたい場合があります。これは、子と参照の専門分野で可能です。子または参照を専門化する場合、ターゲット typ を絞り込み、場合によっては名前も変更します。例: B を拡張する概念 A があり、概念 C にターゲットタイプ B の参照 r がある場合、C のサブコンセプトで参照 r のタイプを絞り込むことができます。これは、コンセプトの子に対しても同じように機能します。
特殊化 : セクションをリンク宣言に追加し、変更するスーパーコンセプトからのリンクを参照する必要があります。
エイリアス
コードから conceptAlias と呼ばれるエイリアスは、オプションで、MPS によって Concept の表現として認識される文字列を指定します。エイリアスは、完了ボックスに表示され、エイリアスまたはその一部がユーザによって入力されるたびに MPS は、コンセプトをインスタンス化します。
コンセプトのアイコン
各コンセプトにはアイコンを指定できます。このアイコンはメニューでコンセプトを表し、複数のコンセプトの中からコンセプトを識別しやすくします。アイコンは、リソース記述言語を使用して記述することも、ファイルとして指定することもできます。どちらのオプションでも、新しい UI で使用する代替アイコンを指定できます。
制約付きデータ型
制約付きデータ型を使用すると、正規表現で制約された文字列ベースの型を定義できます。MPS は、この制約付きデータ型のすべてのプロパティ値が制約に一致する値を保持することを確認します。正規表現の値は、Java 文字列リテラルで正規表現を使用するための規則に従う必要があります。つまり、Java コンパイラーによって Java 固有のエスケープ文字として処理されないように、すべての '\' 文字を '\\' として複製する必要があります。
列挙型
列挙を使用すると、事前定義されたセットの値を保持するプロパティを定義できます。
各列挙メンバーには、名前とオプションのプレゼンテーションがあります。
名前(左の列)- この文字列値は、プログラムでこのメンバーを参照するために使用されます。
プレゼンテーション(右の列)- この文字列値は、ユーザーモデル(完了メニュー、エディター)の列挙型メンバーを表すために使用されます。プレゼンテーションが明示的に定義されていない場合は、代わりに名前が使用されます。
メンバーのセットとは別に、各列挙はオプションでデフォルトのメンバーを定義できます。デフォルトメンバーは、他の値が明示的に設定されていないすべてのプロパティに存在する暗黙的な値と見なすことができます。
プログラムによるアクセス
プログラムでアクセス列挙し、そのメンバーに、列挙型の操作と jetbrains.mps.lang.smodel 言語で定義された enummember タイプを使用します。
列挙メンバーは、名前とプレゼンテーションを照会できます。プロパティの値を列挙データ型の値と照合するには 、is 操作を使用します。
名前 から、プレゼンテーションから 、列挙型のメンバー操作から、メンバーへのアクセスを提供します。
enum switch ステートメントは便利な制御構造を提供します。列挙型メンバーが与えられると、enumswitch ステートメントを使用して特定のメンバーインスタンスに簡単に切り替えることができます。
または列挙型 switch 式:
一部の列挙メンバーが省略され、他にブランチが指定されていない場合、非網羅的なスイッチを報告する警告が発生します。同様に、スイッチで 1 つの値が複数回発生すると、エラーが発生します。
列挙データ型 (非推奨、代わりに列挙を使用)
列挙型データ型を使用すると、事前定義セットの値を保持するプロパティを使用できます。
各列挙データ型メンバーには、値とプレゼンテーションがあります。オプションで、識別子を明示的に指定できます。
プレゼンテーション vs: 価値 vs: 識別子
プレゼンテーション - この文字列値は、UI で列挙型メンバーを表すために使用されます (補完メニュー、エディター)
値 - この値は、そのタイプがメンバータイププロパティによって設定され、コード内の列挙型メンバーを表します
識別子 - このオプションの値は、生成された Java 列挙型の名前として使用されます。この値は、言語ユーザーに対して透過的であることが意図されており、言語では意味がないため、通常、プレゼンテーションまたは値のいずれかから導出されます。ID 派生プロセスが一意の有効な識別子を生成できない場合にのみ指定する必要があります。
名前 - コードから列挙型データ型のメンバーにアクセスする場合、名前は、アクティブなオプションメンバー識別子に応じて、プレゼンテーション、値、または識別子のいずれかを参照します
識別子の自動導出
表示または値から識別子を派生させるとき、MPS は Java 識別子で許可されていない文字を排除するために最善の努力をします。複数の enum データ型メンバーの派生識別子が同じになると、エラーが報告されます。そのような場合は、明示的な識別子を指定する必要があります。
プログラムによるアクセス
列挙型データ型とそのメンバーにプログラムでアクセスするには、jetbrains.mps.lang.smodel 言語で定義された列挙型操作を使用します。
enum データ型の値に対してプロパティの値をチェックすることは、is 操作で行うことができます。プロパティ値の表示を印刷するには、まず対応する列挙型メンバーを取得する必要があります。
属性
属性は、アノテーションと呼ばれることもあり、言語設計者が直交言語構造を表現し、変更することなく既存の言語に適用できるようにします。例: ジェネレーターテンプレートを使用すると、LOOP、-> $、$[] などの特別なジェネレーターマークをターゲット言語に埋め込むことができます。
ターゲット言語(この例では BaseLanguage)は MPS ジェネレーターについて何も知る必要はありませんが、ジェネレーターマクロは抽象モデル(AST)に追加してエディターで編集できます。同様に、アンチクォーテーションとパターンは、BaseLanguage の概念に起因する可能性があります。
MPS は 3 種類の属性を提供します。
LinkAttribute- 参照にアノテーションを付ける
NodeAttribute- 個々のノードにアノテーションを付ける
PropertyAttribute- プロパティにアノテーションを付ける
これらを拡張することで、既存の言語に独自の追加を導入することができます。使用中の属性の良い例については、説明コメントクックブックと要求追跡言語クックブックを調べましょう。
構造のヒントとコツ
構造化言語は、概念定義を簡単に作成、変更、改善できるいくつかの便利なインテンションを提供します。
子を参照にして元に戻す
「子」セクションの定義は参照に変更できます。
逆方向も可能です。
コンテキストアシスタントのヒント
コンセプト定義の下部に表示されるコンテキストアシスタントでは、次のことができるいくつかのクイックアクションが提供されます。
コンセプトのエディターを作成する
コンセプトに「ルート可能」フラグを設定する
INamedConcept を「実装された」インターフェースコンセプトとして追加する
概念をインターフェースの概念に、またはその逆に変換する
これは、適切なインテンションを選ぶのと同じくらい簡単です。
そして両方向で動作します:
参照概念を作成する
これにより、現在の概念への参照を保持する新しい概念が作成されます。コンセプトへの参照を許可するのと同じくらい簡単です。
概念を抽象的、最終的、ルート可能にする
エディターに直接入力してこれらを設定することもできますが、インテンションが好みかもしれません。
デフォルトのエディターを生成する
エディター定義を作成し、概念のプロパティ、子、参照を入力できます。コンセプトの内容に応じて、通常は次の 2 つのオプションを使用できます。
式のような - セルを 1 行に配置し、編集可能な各セルの先頭に対応するロールの名前を追加します
ステートメントのような - ブロックのような方法でセルを配置します
これらは、後でエディター定義自体で再生成できます。
関連ページ:
基本的な考え方
この章では、基本的な MPS の概念であるノード、概念、言語について説明します。これらは、MPS の仕組みを正しく理解するための鍵となります。これらはすべて、他の要素と組み合わせることで初めて意味を成すため、すべて一緒に説明する必要があります。このセクションの目的は、各要素の本質を説明することです。詳細については、ノード、概念 (構造言語)、言語 (プロジェクト構造) に関するセクションを確認することを検討してください。抽象構文木 (AST):MPS は、テキスト形式を避けることによって他の多く...
制約
構造言語は、言語構造に対する高度な制約を表現するには不十分な場合があります。制約アスペクトは、そのような追加の制約を定義する方法を提供します。デフォルトの具体的な概念:抽象概念の場合、制約アスペクトを使用して、抽象概念のノードを作成する必要がある場合に代わりにどの概念を使用するかを示すことができます。例: 子コレクションが AbstractCommands を保持することになっていて、ユーザーが Enter キーを押して新しい子をコレクションに挿入すると、EmptyLine コンセプトのノードが...
アイコンの説明
アイコン記述言語は、さまざまな MPS 要素(概念、アクションなど)のアイコンの記述とインスタンス化に役立ちますこの言語には、次の 2 つの目的があります。クイックアイコンプロトタイピング用のツールを提供する (たとえばコンセプトの新しいアイコンを作る)、アイコンを拡張可能な言語構造にする、第一印象:MPS 言語定義言語でアイコンが必要な場合は、既存の .png ファイルを指す代わりに、目的のアイコンのテキスト説明を入力できます。jetbrains.mps.lang.resources には、...
説明コメント
ノードに属性を追加する機能を活用する方法を学びます。この機能は、構造の章の属性のセクションで詳しく説明されています。このクックブックでは、電卓チュートリアル言語に簡単な追加機能を作成して、電卓定義の入力フィールドと出力フィールドに説明的なコメントを付けることができます。これらの説明コメントは、入力フィールドと出力フィールドに対応する Swing テキストフィールドに添付された「ポップアップツールチップ」の形式で、生成された Java コードに伝達されます。計算機の言語:実験のテストベッドとして...
要求追跡言語
このクックブックでは、要件追跡サンプルプロジェクトについて説明します。このサンプルプロジェクトは、言語にとらわれない要求追跡を実装しています。その過程で、いくつかの便利な言語構成要素が例示されています。異なる言語のノードにアノテーションを付けるノード属性、コンセプトごとの複数のエディター(プレゼンテーション)とエディターヒントによるそれらの切り替え、選択されたエディターへのプログラムによるアクセスヒントとエディターのプログラムによる選択、参照のコレクションでの繰り返しを避けるための参照スコープ、...
言語定義
言語はアスペクトモデルを使って定義されます。言語定義の個々の側面に関する詳細については左側のパネルをチェックしてください。言語プラグインのインストール方法構造