コマンド処理アプリケーションを実装するにはどうすればよいですか?


9

数値を受け取り、その数値でコマンドを処理するシンプルな概念実証アプリケーション(REPL)を作成したいと考えています。

例:1から始めます。次にadd 2、「」と書いて、3を与えます。次にmultiply 7、「」と書いて、21を与えます。次に、素数かどうかを知りたいので、「is prime」と書きます(現在の数値- 21)、それは私に偽りを与えます。「is odd」は私に真実を与えるでしょう。等々。

さて、コマンドが少ない単純なアプリケーションの場合、単純なものでもコマンドswitchを処理できます。しかし、拡張性が必要な場合、機能を実装するにはどうすればよいですか?コマンドパターンを使用しますか?言語用のシンプルなパーサー/インタープリターを構築できますか?「multiply 5 until >200」のようなより複雑なコマンドが必要な場合はどうなりますか?再コンパイルせずにそれを拡張する(新しいコマンドを追加する)簡単な方法は何でしょうか?

編集:いくつかのことを明確にするために、私の最終的な目標はWolframAlphaに似たものを作ることではなく、(数値の)プロセッサのリストを作ることです。しかし、最初はゆっくりと始めたいと思います(単一の数値について)。

私は、Haskellを使用してリストを処理する方法に似たものを念頭に置いていますが、非常に単純なバージョンです。コマンドパターン(または同等のコマンド)のようなもので十分か、それとも目標を達成するために新しいミニ言語とパーサーを作成する必要があるのか​​と思いますか。

Edit2:すべての回答に感謝します。すべては私にとって非常に役に立ちましたが、エマッドカリームが最も私を助けてくれたので、それを答えとして選びます。再度、感謝します!


2
反対票は取れません。次回の質問をよりよくまとめられるよう、理由をお聞かせください。
Nini Michaels

2
私はこの質問が本当に好きです。人々が提案するデザインを見て楽しみにしています。オブジェクト指向の設計を特に探していますか(OOパターンであるコマンドパターンについて言及しています)。
Bjarke Freund-Hansen

ありがとう:)はい、私はOOPを好みますが、他の方法が提案されてもかまいません!
Nini Michaels

2
非常にクールなプログラミングの主題である逆ポーランド記法の実装のようです!
Alberto De Caro

2
あなたは、おそらくのファウル下落しているブックからの句を、私がすべき質問の種類は何ではないここに頼みますか?FAQで、つまり、あなたの質問に答える本全体を想像できるなら、あなたはあまりにも多くを求めています。
Mark Booth

回答:


5

これは通訳のように聞こえます。詳細な機能よりも実装について心配しているようです(ここでは推測しているだけです)。このプロジェクトを拡張するのは簡単なことではありません。時々しか機能しないパッチが1000個ある製品ではなく、信頼性の高い製品を入手するための特別な開発アプローチではなく、エンジニアリングアプローチが必要であるため、範囲を明確に検討してください。

構文を決定し、構文解析して、必要な構文チェックを実行する準備をします。このリンクはこれに役立ちます:独自のパーサーを作成します

見てみましょう:このトピックは作業のさまざまな側面に触れているため、役立つリンク(特にRMKによる回答)もあります。:言語インタープリターの作成Ultimate Programmable Scientific Calculatorでやや似ている、見栄えの良いプロジェクトの例を見たいと思うかもしれません。コマンドラインC#インタープリターのソースコードと作業プログラムは、こちらのCommand-Line-Implementation-of-C#-Made-for-Teachingにあります。コンパイラーを使用して、構文解析や変数の型指定などの複雑なタスクを実行することは、これらすべてを自分で書くことの複雑さを回避するための賢明な方法かもしれません。また、Charshシェル機能を提供するMonoオプションもあります。CsharpReplです。


ありがとう、あなたのリンクは本当に役に立ちます!ですから、簡単に拡張したいのであれば、通訳が一番いいと思います。
Nini Michaels

フィードバックをありがとう、CodeProjectへのリンクから始めるのは良い考えだと思います。
NoChance

2

自分で実際のパーサーを作成することに特に関心がない場合を除き、パーサージェネレーターフレームワークの1つを確認することをお勧めします。Cの場合はYACCまたはBisonを使用しますが、必要に応じて他の言語の代替手段を用意する必要があります。

これらにより、複雑な文法の解析の複雑さが取り除かれ、実行したいタスクに集中できます。もちろん、これは質問で提案する文法にとってはやり過ぎかもしれませんが、後でより複雑な文法に拡張するオプションがあると述べているので、これらのフレームワークからインスピレーションを得ることは少なくとも価値があります。


1
ほとんどのパーサージェネレーターの問題は、アーティファクトが静的であり、簡単に拡張できないことです。OPは、「ルール」(キーワードと構文)が柔軟なデータ構造に格納され、各入力の後に評価されるルールエンジンのようなもので提供するほうがよいと思います。
TMN

2

あなたが説明しているのはスタック言語に非常に近いものです。

たとえばFactorでは、あなたが説明することは次のようになります

1
2 +
7 *
even? not

または、独自の単語を定義して、次のように使用することもできます

: add ( x y -- sum ) + ;
: multiply ( x y -- product ) * ;
: odd? ( n -- ? ) even? not ;

これらの定義により、上記の例は次のようになります。

1
2 add
7 multiply
odd?

通常、スタック言語はスペースで区切られた単一の単語を使用するため、解析するのは簡単です。Factorをご覧になることをお勧めします-それはあなたが望むものであるかもしれません。必要な処理を行う単語を簡単に定義できます。

編集:実際に類似した言語を設計したい場合は、いずれにせよそれらのいずれかで遊ぶことをお勧めします。スタック言語の解析は簡単です-空白で分割し、単純な処理の実装は簡単です。スタックで何が発生するかを処理する必要があるだけです。


これはかなり簡単に聞こえ、開始するのに良い場所です。ありがとう!
Nini Michaels

1

しかし、拡張性が必要な場合、機能を実装するにはどうすればよいですか?

すべきではない。拡張性は、ほとんど利益を得ることなく、多くの複雑さを生み出します。つまり、既存の状態へのフックを提供する必要があります。状態を表示し、状態を変更し、他の結果を返すメカニズムを提供する方法(画面に出力)。コアコードがモジュールを発見してロードし、コマンドをそれらにディスパッチする方法が必要です。

コマンドパターンを使用しますか?

できますが、おそらく適切ではありません。

入力全体を受け取って処理のために送信するのではなく、入力を解析して適切なハンドラーにディスパッチし、その処理を実行させます。コマンドはその通信で変わりません。したがって、コマンドパターンはありません。

言語用のシンプルなパーサー/インタープリターを構築できますか?

入力をトークンに分解する処理が必要になります。拡張可能なソリューションの場合、おそらくこれ以上は行いません。明確に定義されたソリューションでは、完全な解析ツリーを使用すると、パフォーマンス、エラー処理、およびデバッグ機能が向上します。

むしろ(数の)プロセッサのリスト

次に、おそらくLISt処理言語を調べる必要があります。コードとデータの並置は、あなたが説明するものとうまく一致するはずです。


提案ありがとうございます。LISPについては、LISPに精通しており、Haskellにも精通しているので、このアイデアに刺激を受けました。しかし、私はホイールを少し再発明しているかもしれませんが、コマンドの処理と解釈で手を汚したいと思います。したがって、実際の「リスト処理」以外にも教育目的があります:)
Nini Michaels

@NiniMichaelsは確かですが、拡張性の設計に関する限り、lispの編成/コード/データのチェーンを使用することは悪いオプションではありません。
Telastyn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.