4

いいタイトルが思いつかなくてすみません。

問題は次のとおりです。

当社のお客様のために、「シナリオ」の構築に使用できるグラフィカル デザイナーを (より大きなアプリケーションの一部として) 作成しました。

これらのシナリオは、「コマンド」で構成される「コンポジット」で構成されています。これらのコマンド オブジェクトはすべて CommandBase から派生し、ICompilable というインターフェイスを実装します。

シナリオ クラスは ICompilable も実装します。コマンドで Compile() が呼び出されると、バイトの配列が返され、それを目的のデバイスに送信できます (そのハードウェアに関する多くの情報を開示することはできません。申し訳ありません)。

アイデアを与えるために:

var scenario = new Scenario();

scenario.Add(new DelayCommand(1));
scenario.Add(new CountWithValueCommand(1,ActionEnum.Add,1));
scenario.Add(new DirectPowerCommand(23,false,150));
scenario.Add(new WaitCommand(3));
scenario.Add(new DirectPowerCommand(23,false,150));
scenario.Add(new SkipIfCommand(1,OperatorEnum.SmallerThan,10));
scenario.Add(new JumpCommand(2));

byte[] compiledData = scenario.Compile();

グラフィカル デザイナーは、これらすべてをユーザーから抽象化し、ユーザー (または彼女) が単純にコンポジットをデザイナー サーフェスにドラッグ アンド ドロップできるようにします。(コンポジットはコマンドをグループ化できるため、タスクを返すためのビルディング ブロックを提供できます)

最近、私たちの顧客が私たちのところに来て、「デザイナーは本当にクールですが、ある種のプログラミング言語、単純なものを使いたいと思っている人が何人かいます」と言いました。

(もちろん彼らにとっては簡単です)

さまざまなコマンドを呼び出したり、SkipIfCommand をより適切な構造に置き換えたりできる単純な言語を提供したいと考えています。

どこから始めればよいのか、どのような選択肢があるのか​​わかりません (現在持っているものを壊さずに)

Python などの言語を埋め込んでいる人や、独自の言語でパーサーを書いている人などについて聞いたことがあります...

助言がありますか?

PS: ユーザーはコンポジットのみを使用し、コマンドを使用することはありません。コンポジットは実行時に (グラフィカル デザイナーと共に) 動的に読み込まれ、別のアセンブリでサード パーティによって提供される場合があります。

4

6 に答える 6

4

私が理解したと思うことから、あなたには2つの選択肢があります

XML スタイルの「マークアップ」を使用して、エンティティとそのグループを定義できるようにすることもできますが、それは最善ではない可能性があります。

あなたの代替案は、はい、言語を埋め込むことができますが、本当に必要ですか、それはやり過ぎではありませんか?どうすればそれを制御できますか?

本当に単純な構文だけが必要な場合は、おそらく独自の言語を作成してください。厳密で明確な言語を使用している限り、単純なインタープリターを作成するのは実際にはそれほど難しくありません。使用しているコンパイラの例をいくつか探してみてください。C#?

私は大学で Java で非常に単純なインタプリタを書きましたが、あなたが思っているほど難しくはありませんでした。

于 2008-11-04T21:47:19.053 に答える
2

これは、単純な DSL の完璧なシナリオのように見えます。詳細については、 http://msdn.microsoft.com/en-us/library/bb126235 (VS.80).aspx を参照してください。

lua.Net などのスクリプト言語を使用することもできます。

于 2008-11-04T22:08:12.163 に答える
2

本当にシンプルな言語が必要な場合は、「再帰降下パーサー」が必要です。

たとえば、次のような言語です。

SCENARIO MyScenario
DELAY 1
COUNT 1 ADD 1
DIRECT_POWER 23, False, 150
WAIT 3
...
END_SCENARIO

次のような文法があるかもしれません:

scenario :: 'SCENARIO' label newline _cmds END_SCENARIO
cmds::  _delay or _count or _direct_power or...
delay:: 'DELAY' number

次のようなコードが得られます。

def scenario():
    match_word('SCENARIO')
    scenario_name = match_label()
    emit('var scenario = new Scenario();')
    cmds()
    match_word('END_SCENARIO')
    emit('byte[] ' + scenario_name + ' = scenario.Compile();')

def delay():
    match_word('DELAY')
    length = match_number()
    emit('scenario.Add(new DelayCommand('+ length +'))')

def cmds():
    word = peek_next_word()
    if word == 'DELAY':
       delay()
    elif ...
于 2008-11-04T22:11:58.990 に答える
1

これは、バイトコード配列のコンパイルと作成に使用できるDSLを構築するためのPythonicソリューションです。

  1. C#構造をPythonで利用できるようにする簡単なモジュールを作成します。目標は、ユーザーが操作できる各C#クラス(コンポジットまたはコマンドなど)をPythonクラスとして定義することです。

    通常、これには、C#タイプからネイティブPythonタイプへ、またはその逆にさまざまな変換を行う最小限のメソッドセットの実装が含まれます。

  2. これらのPythonクラス定義を使用してスクリプトを作成する方法を示すいくつかの素晴らしいデモを作成してください。Pythonでこのようなものを作成できるはずです。

    import * from someInterfaceModule
    scenario= Scenario(
        Delay(1),
        Repeat( Range(10),
            DirectPower( 23, False, 150),
            Wait(3),
            DirectPower( 23, False, 150)
        )
    )
    scenario.compile()
    

これらは、定義するのが比較的簡単なクラスです。ここでの各クラスは、ベースC#モジュールを直接呼び出すPythonモジュールとして実装するのがかなり簡単です。

構文は純粋なPythonであり、追加の構文解析や字句スキャンは必要ありません。

于 2008-11-04T22:31:45.050 に答える
1

S.Lottのコメントに追加するために、C#からPythonスクリプトを評価する方法を次に示します。

于 2008-11-04T22:36:41.420 に答える
0

このミニ言語を作成してすべてコーディングするのはとても楽しいかもしれませんが、実際に尋ねなければならない質問は次のとおりです。

  1. この機能/機能を追加するビジネス ケースは何ですか?
  2. この機能に誰がお金を払うのでしょうか?
  3. あなたがこの機能を構築した場合、誰がこの機能を「承認」しますか?

「本当にきちんとした」機能は、そのような要求に対する真の答えが「いいえ」であることを現実が示している場合に構築される方法があります。

続行する前に、これを後援してくれる利害関係者がいるかどうかを確認してください。次に、プロジェクトにコミットする前に、エンド ユーザーが本当に望んでいるものを確認します。

乾杯、

-R

于 2008-11-04T23:57:34.313 に答える