質問

本物の、誠実な外部 DSL を構築するためのツールは何ですか。いいえ、私は Ruby、Boo、XML、または別の既存の言語や構文を悪用することについて話しているのではありません。本当の外部 DSL、つまり私自身の目的のための私自身の言語のことを指します。

いくつかの言語ワークベンチが開発されていることは知っていますし、.NET の "Irony" などについて聞いたことがあります。もちろん、ANTLR、Lex/Yaac などもありますが、私がやろうとしていることには複雑すぎるのではないかと思います。

あなたが使用したり聞いたりしたことがある DSL ビルダー ツールについて、またそれがどのように役立つか、またその欠点についての印象について話してください。

役に立ちましたか?

解決

私は Boo、Irony.NET、および Grammatica と呼ばれるツールキットで DSL を作成しました。あなたは、パーサージェネレーターは複雑すぎると言っていますが、判断が性急すぎるのかもしれません。実際、少しの学習曲線を乗り越えれば、それらは非常に簡単に使用でき、簡単にオーバーライドできる広大な可能性の世界を開きます。努力。ほとんどのパーサー ジェネレーターの文法を記述するために必要な表記法の学習は、正規表現の学習に似ていることがわかりました。正規表現を理解するには、少し頭を曲げる必要がありますが、得られるメリットは大きいです。

私の意見は次のとおりです。ターゲット言語が、単純なビジュアル デザイナーでも扱えるほど単純であれば、パーサー ジェネレーターを使用して文法を記述するのは非常に簡単です。

ターゲット DSL が文法を書くのに汗を流す必要があるほど複雑である場合、機能を低下させたビジュアル ツールではいずれにせよ役に立たず、結局は文法の書き方を学ぶ必要があります。

ただし、長期的には、内部 DSL と外部 DSL の違いについては同意します。私は Boo で内部 DSL を作成し、それを機能させるために DSL 構文を変更する必要がありましたが、それは常にハックのように感じられました。Irony.NET または ANTLR を使用すると、同じ文法をより柔軟に実行できたはずです。

私は持っています ブログ投稿 いくつかのオプションについて話し合っています。この投稿は実行時式評価用の DSL の作成を中心にしていますが、ツールはすべて同じです。

Irony.NET に関する私の経験はすべて肯定的であり、Irony.NET を使用して実装された参照言語がいくつかあるため、そこから始めるのが適切です。言語が単純であれば、立ち上げて実行するのはまったく複雑ではありません。CodeProject には TinyParser と呼ばれるライブラリもあります。これは非常に興味深いものです。純粋なソース コードとしてパーサーを生成するため、最終製品にはサードパーティの参照がまったく含まれません。自分では使ったことないけど。

他のヒント

スタンドアロン DSL の作成を検討している場合は、コンパイラの構築を検討していることになります。これを回避する方法はありません。コンパイラの構築 必須のプログラミング知識が必要ですが、実際には一般に考えられているほど難しくありません。スティーブ・イエッグの 正しいプログラマーの食事 コンパイラをうまく構築する方法を知ることの価値をまとめています。

始める方法はたくさんあります。この記事で言及されている 2 つの論文をチェックすることをお勧めします。 コンパイラを書きたいですか?この 2 つの論文を読んでください. 。最初の1つ、 コンパイラを作ってみましょう, 、非常にアクセスしやすいです。実装言語として Turbo Pascal を使用しますが、ソース コードは非常に明確なので、他の言語でも簡単に実装できます。パスカルは単純な言語です。

物事の仕組みと関連する用語についてよく理解したら、次のような内容を詳しく調べることをお勧めします。 アントラー. 。ANTLR には優れた IDE があり、 ANTLRWorks, 、インタプリタとデバッガが付属しています。また、文法をその場で非常に優れた視覚化して生成します。それは学習において非常に貴重であることがわかりました。

ANTLR には優れたチュートリアルがいくつかありますが、最初は少し圧倒されるかもしれません。 これです これは優れていますが、ANTLR 2.0 に対応しているため、より新しいバージョン (現在の最新バージョンは 3.1) と非互換性が発生する可能性があります。

最後に、DSL には別のアプローチがあります。Lisp アプローチ。Lisp の構文のない性質 (コードは基本的に抽象構文ツリーです) を考えると、括弧に慣れていれば、そこから無限の言語を形作ることができます :)。

そのアプローチを採用する場合は、埋め込み可能な Lisp を使用することになります。Javaでは、次のようになります。 クロージュア, 、JVM およびそのライブラリと完璧に相互運用する Lisp 方言です。個人的には使用していませんが、良さそうです。Scheme には GNU があります ガイル, 、つまり LGPLに基づいてライセンスを取得. 。Common Lisp の場合は、 ECL, 、同じくLGPLの下にあります。どちらも相互運用性のために C インターフェイスを使用しているため、他の言語にほとんど埋め込むことができます。ECL は、各 Lisp 関数が C 関数として実装されるという点で、Lisp の中でも独特です。そのため、必要に応じて Lisp コードを C で書くことができます (たとえば、独自の拡張メソッド内で、Lisp オブジェクト上で動作する C 関数を作成できます)。そしてLispから呼び出します)。私はしばらくの間、自分のサイドプロジェクトで ECL を使用してきましたが、気に入っています。メンテナーは非常に活発で、対応が丁寧です。

本当にチェックアウトする必要があります ラゲル. 。これは、通常のソース コードにステート マシンを埋め込むためのフレームワークです。Ragel は、C、C++、Objective-C、D、Java、および Ruby をサポートしています。

Ragel は、ファイルやプロトコルのパーサーを作成したり、外部 DSL をステップ実行したりするのに最適です。主な理由は、状態遷移などであらゆる種類のコードを実行できるためです。

Ragel を使用するいくつかの注目すべきプロジェクトは次のとおりです。 雑種, 、素晴らしい Ruby Web サーバーです。そして プリコット, 、Ruby ベースの HTML パーサーで、jQuery からインスピレーションを得たものです。

Ragel のもう 1 つの優れた機能は、 グラフビズステートマシンを視覚化するベースのチャート。以下はから抜粋した例です ゼッド・ショウの ラジェル状態図に関する記事.

ragel state chart

テキスト このために作られました。

ウェブサイトより:

Xtextは、プログラミング言語とドメイン固有の言語の開発のためのフレームワークです。

パーサーから、リンカー、コンパイラ、またはインタープリターを介して、完全に吹き飛ばされた最高級の日食の統合まで、完全な言語インフラストラクチャのすべての側面をカバーしています。これらすべての側面に適したデフォルトが付いており、同時にすべての側面をニーズに合わせて調整できます。

私は Irony を使用して良い結果を得ています。Irony の優れた点は、DSL を使用するどのランタイムにも簡単に組み込めることです。私は C# で書かれたセマンティック モデルに入力する外部 DSL を作成しているので、皮肉なことに素晴らしいですね。次に、セマンティック モデルを使用して、StringTemplate でコードを生成します。

外部 DSL の実装を計画している場合は、Spofax ( http://strategoxt.org/Spoofax ) は、これを行うための優れた言語ワークベンチです。これは、SDF や Stratego などのいくつかの最先端テクノロジーを活用した、パーサーベースのテキスト言語ワークベンチです。DSL 実装に加えて、コード補完、アウトライン ビュー、インテリセンスなどの非常に豊富なエディタ サービスを利用できます。これは、いくつかの言語を構築するために使用されてきました。 http://mobl-lang.org/. 。提供されるサポートについては、こちらをご覧ください。

Spofax プロジェクトには、すぐに使える優れたサンプル DSL 実装と Java コード ジェネレーターが付属しています。これは、ツールを使い始めるための出発点として機能する可能性があります。

この言語ワークベンチの使用法に関するチュートリアルの詳細は次のとおりです。 http://strategoxt.org/Spoofax/Tour.

それが役に立てば幸い!

深刻な外部 DSL の場合、解析の問題を避けることはできません。ANTLR は必要最低限​​のものです。チェックしたいのは、任意の DSL 構文を Java などのターゲット言語にマップするために使用できるプログラム変換システムです。

見る http://en.wikipedia.org/wiki/Program_transformation

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top