よほほ!
前回の投稿では、入力された気象データの配列、またはデータ「時間+温度」を追加できるという事実に焦点を当て、 ビヘイビアの使用を少し試みて、概念を見つけました。
これまでのところ、便利な何かをする時が来ました。これまでのところ、クールな構文を除いて、実装したすべてのものを他の言語で実装できるからです。
まず、時間制限を導入します。 次に、時間を0〜24の範囲に、分を0〜60に制限します。そうしないと、コンパイルエラーが発行されます。
制約
制約は、概念実装の有効性を担当する言語の側面です。 この場合、 プロパティの時間と分を制限する必要があるため、時間の概念の制約の側面を作成します。
ここでは、ASTの構造に関与する3つのポイントがあります。
- 子にすることができます:ノード、親ノード、子、および可能なすべてについての入力を取得し、このコンテキストでの概念の実装が子であるかどうかを決定します
- 親にすることができます:子と同じ、親ノードである可能性の確認のみ
- 祖先にすることができます:すべては親と同じですが、より多くのネスト:この場合、文字通りASTに達することができます-ノードを祖先にすることができます
さらに、プロパティのいくつかの特性を定義できます。 これが必要なものであり、現時点では十分に把握できているので、まだスコープを気にする必要はありません。
原則として、すべてがシンプルで明確です 。ゲッターとセッターを再定義できますが、関心があるのは有効です 。 その中で、 propertyValueと現在のノードを入力として取得します 。 単純な条件があり、Javaで記述するように記述します。
ここで、言語を収集してサンドボックスに突っ込んだ場合、時間の値> = 24または<0かどうかを表示する必要があります。
実装を数分で記述することは難しくありません。
だから、素晴らしい、それは動作します。 さて、これをJavaに翻訳してみる価値はあります。それは、私たちがすべてをやったわけではないからです。
最初にGeneratorアスペクトを追加し、 mainを呼び出します。
空なので、新しいルートマッピングルールを作成します。 コンセプトフィールドで、ルートコンセプトPredictionListを選択し、矢印の右側で、Alt + Enter→ 新しいルートテンプレート → Javaクラスを押します。 論理的には、次のようになります。
map_PredictionListを開くと 、その上にメタ情報を持つJavaクラスのようなものができます。
これがテンプレート、テンプレートであり、一般的に最も重要な出発点です。 しかし、1つのポイントがあります。WeatherTimedDataをいくつかのプリミティブに変換したくないのですか? WeatherTimedDataクラスのオブジェクトが必要ですが、ここにはバムがあります! このようなクラスはありません! 手で書けるように。 これを行うには、新しいSolutionを作成し、必要なものを呼び出します。最も重要なことは、クラスを作成できるようにjetbrains.mps.baseLanguageを使用言語に追加することです。
私は次のようにそれらを得ました:
ここで、Javaコードの世代でこれを使用する方法を学ぶ必要があります。 ジェネレーターのモデルプロパティに移動し、WeatherClassesを依存関係に追加して、 export = trueをクリックします。
これで、これらのクラスを生成で使用できます。これは今から行います。
単純なクラスのように見えますが、名前がPredictionListという名前の値を持つようにする必要があります。 ピーターの天気予報-ピーターはそこにいます。 モスクワの場合-モスクワがあります。 「Here should be city」という行をクリックし、Alt + Enterホットキーを使用して、ドロップダウンリストでプロパティマクロを選択します。
ポイントは非常に単純です-PredictionList型のノードが与えられ、文字列を返す必要があります。 行の横に表示されるドル記号をクリックして、インスペクターでコードを編集します。
プロジェクトを組み立て、サンドボックスソリューションを開きます。ここでは、サンクトペテルブルクの天気情報のみを入力し、RMB→生成されたテキストのプレビューをクリックすると、実際のJavaが作成されます。 今ではそれをスクリーニングすることはできませんが、コピー&ペーストで静かに破棄します。
package WeatherPrediction.sandbox; /*Generated by MPS */ import WeatherClasses.structure.PredictionList; public class PredictionListImpl extends PredictionList { /*package*/ String name = "Saint Petersburg"; }
importステートメントに注目する価値があります。MPSはPredictionListのインポートを生成しました。これは別のSolutionとして作成しました。 このようなソリューションは、「ヘルプ」、「サポートソリューション」と呼ぶことができます。 まあ、私は個人的にそれを彼らと呼ぶのが本当に好きです。
それでは、入力配列の別の実装を追加しましょう。
入力データを格納する空のlinkedlistを作成します(その理由はありません)。
コンストラクターでは、2つのクールなマクロを一度に使用します。
マクロ$ LOOP $は以下を実行します。このコレクションを通過し、各要素に対して何かを実行します。 その結果、生成されたデータの配列が次々に送信されます。 この場合、 node.weatherData.itemsを繰り返し処理します
マクロ$ COPY_SRC $は 、ある概念の別のモデルへの変換結果を取得するために使用されます。 現在のところ、テンプレートは1つしかありません。これは「メイン」テンプレートであり、 PredictionListのテンプレートです。MPSは何をどのように行うかをどのように理解しますか?
そのような瞬間に、MPSはメインジェネレーターの構成を調べます。つまり、現在は空になっている縮約ルールを調べます。
PredictionListで行ったのとまったく同じことを行っています。
reduce_WeatherTimedDataに移動し、Shift +スペースを押して、「式」を選択します。 今書いて
new WeatherTimedData(0, 0, null)
次に、このExpressionをTemplateFragmentでラップする必要があります。TemplateFragmentのコンテンツは、メインのPredictionListImplで使用されます。
ctrl + wホットキーを使用して式全体を選択し、Alt + Enterキーを押してテンプレートフラグメントを作成します。
ここで、ゼロをプロパティmacroに置き換える必要があります 。これは、既に実行方法がわかっています(0を押して、Alt Enterを押し、プロパティマクロを追加します。インスペクタで、
(templateValue, genContext, node, operationContext)->int { node.time.hours; }
これは、0を現在のクロック値に置き換えることに相当します。 分についても同じことを行い、nullを置き換えません-私はあまりにも怠zyですが、考え方は同じです- 温度概念の削減ルールを追加し、 プロパティマクロの代わりにマクロ$ COPY_SRC $を使用します
その後、0と0を既に呼び出し可能なプロパティマクロに置き換えます(0、Alt + Enterを選択→プロパティマクロを追加→ node.time.minutes )。
言語を収集し、Sandboxソリューションに進みます。
それで、Weather
ソースコードについて
Weather prediction rules for Saint Petersburg [ 0 : 23 ] { temperature = 23.3 °C } [ 12 : 24 ] { temperature = 100.0 °F } [ 23 : 33 ] { temperature = 4.4 °C }
次のJavaコードが判明します。
package WeatherPrediction.sandbox; /*Generated by MPS */ import WeatherClasses.structure.PredictionList; import java.util.Deque; import WeatherClasses.structure.WeatherTimedData; import jetbrains.mps.internal.collections.runtime.LinkedListSequence; import java.util.LinkedList; public class PredictionListImpl extends PredictionList { /*package*/ String name = "Saint Petersburg"; /*package*/ Deque<WeatherTimedData> input = LinkedListSequence.fromLinkedListNew(new LinkedList<WeatherTimedData>()); public PredictionListImpl() { LinkedListSequence.fromLinkedListNew(this.input).addElement(new WeatherTimedData(0, 23, null)); LinkedListSequence.fromLinkedListNew(this.input).addElement(new WeatherTimedData(12, 24, null)); LinkedListSequence.fromLinkedListNew(this.input).addElement(new WeatherTimedData(23, 33, null)); } }
linkedlistを通常の配列に置き換えることは可能ですが、インデックスを突き出す必要があるため、より困難になります。 ArrayListに置き換えることもできますが、リンクリストを推奨したのはMPSが最初でした。 WeatherDataの個別のサポートクラスを作成して、コンストラクタにデータを追加するのではなく、生成されたコードを改善する多くの方法があります。 またはさらに悪い。 一般に、今では言語からJavaコードを生成できます(!)。 一般に、 Generatorの知識を習得したため、他の言語のJavaコードを生成できるようになりました!
ご清聴ありがとうございました。