2017-08-09 14 views
1

自然言語を解析する最も効率的な方法は何ですか?自然言語の解析

Set the alarm for *. 
Call *. 
Get me an * at * for *. 

とそれに対応する機能:

は、 "文字列" はのようなmap<string, void (*func)(int,char**)>含む文字列とします。 「入力」を取ると、マップ内の文字列のいずれかにマッチするようにparseとしての機能を実装するためにどのように

Call David. 

:今、「入力が」のような文を含むstringであると仮定します。次に、対応する関数を呼び出し、すべてのワイルドカードエンティティ(*が文字列内にある)を含むargcとargvを渡します。そのような機能を実装する最も効率的な方法は何ですか?

+1

あなたが定義済みのリストを持っている場合実在でない固定プレースホルダを持つコマンド自然言語ですが、ドメイン固有の言語や多くの場合正式な言語(Google DSLドメイン固有の言語)に似ています。したがって、コマンドに一致する正規表現のセットを定義し、たとえばプレースホルダを抽出することができます。しかし、あなたの質問は簡単にそれに簡単に答えることができます。 – xander

+0

スタイルコメント:C++ 11以降は 'std :: function >)'と書いています。 – MSalters

答えて

1

この質問にはなぜdownvoteがあるのか​​分かりません。それはよく自明ではない。

構文解析には多くの学術的アプローチがあります。これは、縮退文法ではほとんど必要です。 「自然言語」はおそらく明確な用語ではなく、自然言語にはあいまいさがありますが、そのような制約付きサブセットは問題になりません。

この特定の例では、異なる制作ルール(マップエントリ)が相互にあいまいではないことがわかります。実際、最初のトークンで曖昧さを解消するには十分です。 std::mapがソートされているので、そのトークンの効率的なO(log N)検索を実行できます。

したがって、置換を導出すればよい。ここでも、縮退したケースは無視します。誰も"Get me an at at at for atを気にするつもりはありません。 "`、それは明確に解析するにもかかわらず。

代わりに、あなたが予想される次のトークンを取得するまでの置換のためにあなたは、単にトークンを集める。Get me an * at * for *.は、最初*atにすべてのトークンを取得することを意味します二*収集はforまでトークン、および最終*は、残りのすべてのトークンを取得します。

あなたは何のバックトラックが必要とされていないことを参照してください。構文解析に失敗した場合は、単に一致するものがない。

関連する問題