TextGen
TextGen 言語アスペクト
導入
TextGen言語アスペクトは、テキスト変換へのモデルを定義します。モデルを直接テキスト形式に変換する必要があるたびに便利です。この言語には、テキストを出力し、ノードをテキスト値に変換し、出力に合理的なレイアウトを与えるための構成要素が含まれています。
操作
appendコマンドは変換を実行し、結果のテキストを出力に追加します。モデルの問題を報告するためにfound errorコマンドを使用できます。with indentコマンドは、インデントを大きくしてブロックを区別します。あるいは、深さ増加コマンドおよび深さ 減少コマンドは、ブロック構造に限定されることなく、現在のインデント深さを操作します。indent bufferコマンドは、現在の行に現在のインデントを( identまたは深さの増減で指定されたとおりに)適用します。
演算命令 | 引数 |
---|---|
append | 任意の数
|
found error | エラー・テキスト |
decrease depth | これからインデントレベルを下げます |
increase depth | これからインデントレベルを上げる |
indent buffer | 現在の行に字下げを適用する |
with indent { <code> } | のインデントレベルを上げる |
インデント
根本的な原則を理解すれば、正しいインデントは簡単に得られます。TextGenはASTをテキストにフラッシュします。TextGenコマンドは単に出力バッファを順番に操作して、一度に1ノードずつそこにテキストを出力します。現在のインデントの深さ( インデントバッファ )を保持している変数は、それぞれの根の概念に対して保存されます。インデントバッファはゼロから始まり、深さの増減とindentコマンドで変更されます。
ただし、「インデント」はappendコマンドで明示的に出力ストリームに挿入する必要があります。ブロックを単にindentでマークしても、ラップされたTextGenコードによって生成されたテキストは自動的にはインデントされません。with indentブロックはインデントバッファの値を増やすだけですが、個々の追加は現在のサイズのインデントバッファを前に付けることを望むかもしれません。
インデントバッファを出力ストリームに明示的に挿入する方法は2つあります。
インデントバッファコマンド
appendコマンドのパラメータに対するインスペクタのindentフラグ付き
例:定数のリストの中で定数を適切にインデントするために、発行された各行の先頭でindent bufferを呼び出します。これにより、インデントは各行の先頭にのみ挿入されます。
あるいは、appendコマンドの最初のパラメータにインスペクタでwith indentフラグを指定することもできます。これはまた各行の始めにだけ字下げを挿入します。
ルートの概念
TextGenには、2種類のルート概念があります。
概念テキストへの変換をエンコードするConceptTextGenDeclaration概念によって表現されるテキストgenコンポーネントコンポーネント。ルート可能な概念の場合、ターゲットファイルも指定できます。
LanguageTextGenDeclarationの概念で表される基本テキストのgenコンポーネント。再利用可能なtextgen操作とユーティリティメソッドを定義できます。これらは、拡張言語と同じ言語の他のテキストgenコンポーネントから呼び出すことができます。
拡張概念でのTextGen
MPSはルート概念用のファイルを自動的には作成しません。TextGenが定義されている概念の下位概念でも、ファイルは自動的には作成されません。厳密な概念の一致のみが考慮されます。拡張概念が祖先のtextgenコンポーネントをそのまま再利用することを望むなら、それ自身の空の TextGenコンポーネントを宣言し、その本質をファイル名、符号化および拡張として述べ、コンポーネントの本体を空のままにします。
レイアウト
出力ファイルのレイアウトを制御するための暫定的なメカニズムがあります。(のみrootable概念で入手可能)ConceptTextGenDeclarationのテキストレイアウト部は、作成者が(デフォルトのもので)複数の論理セクションを定義し、必要に応じてテキストを追加するためにどの区間に、それぞれが追加のために指定することができます。
テキストの生成は、物理ファイルの行に対応する順序で常に可能とは限りません。たとえば、Javaソースの場合、インポートと本体の 2つの異なる領域を区別することができます。ここで、インポートは本体と一緒に入力されます。情熱的な言語設計者は、ファイルコメント、パッケージステートメント、インポート、およびフィールドとメソッドからなるクラス本体まで、さらにファイルを分割し、ClassConceptをトラバースしながらそれぞれを個別に作成することができます。それが出力ファイルのレイアウトと呼ぶものです。それは今制御を与えるものです。MPSのベテランは、長年TextGenで利用可能だった2つのバッファ(TOPとBOTTOM)を知っているかもしれません。これらは事前定義された、ハードコードされた値です。出力ファイルの領域とその順序を指定するのは言語デザイナー次第です。
実行順序が変わるため、属性からテキストを生成する場合は特に、個別の領域が便利になります。使って、テキストgenの流れが物理的なテキスト行に対応することを確認するのはさらにトリッキーであり、指定された領域は生成をずっと快適にします。
ファイルのレイアウトは、ファイルを生成するトップテキストのgenに指定できます。
このメカニズムのサポートは暫定的なものであり、現在はかなり初歩的なものです。BaseLanguage実装でそれを利用します。それでこの通知はこれを本番に入れることを奨励するよりむしろ何が起こっているのかをあなたに説明することです。
コンテキスト・オブジェクト
特定のモデルからテキストへの変換シナリオでは、TextGenの間にいくつかのコンテキスト情報を保存することが重要です。たとえばBaseLanguageでは、TextGenはモデルのインポートと修飾されたクラス名を追跡する必要があります。直接テキストバッファ操作に基づく以前のバージョンの面倒で低レベルのアプローチは、概念のtextgen仕様の一部としてカスタマイズされたオブジェクトを定義して使用する可能性に置き換えられました。
現時点では、通常のjavaクラス(概念インスタンスをとる引数なしまたは単一引数のコンストラクターを持つ)がコンテキストオブジェクトとしてサポートされています。通常の変数としてコードからコンテキストオブジェクトを参照します。
TextGenで属性を処理する
ノードに属性の注釈が付けられている場合、これらの属性のTexGenが最初に処理されます。その後、属性のTextGen内の${属性付きノード}構造は、属性ノード自体のTextGenを挿入します。
単一ノードに複数の属性がある場合は、最後に割り当てられた(最上位の)属性から順に処理されます。TextGenが関連付けられていない属性は無視され、スキップされます。
サンプル
これはForeachStatement(jetbrains.mps.baseLanguage)のテキストgenコンポーネントの例です。
これは、テキストgenの人工的な例です。
インデント付きの行数を含む次のコードブロックを生成します。
属性付きノードの出力に追加テキストを追加するattributeのTextGenの例:
関連ページ:

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

マイグレーション
言語が公開され、ユーザーがそれを使い始めた後、言語の作者は言語定義へのさらなる変更に注意しなければなりません。特に、概念を削除したり、プロパティー、子、および概念への参照を追加および削除すると、前の言語バージョンと次の言語バージョンの間に互換性がなくなります。次の言語バージョンに更新すると、言語のユ...