5

オートコンプリートは通常、パーサーによってどのように処理されますか?

例をとると、パーサーに以下を渡します。

"int i=2"

この場合のオートコンプリートオプションには、次のものが含まれます。

"int i=2,"
"int i=2;"

オートコンプリートはパーサーの一部である必要がありますか?

そうでない場合、イベントベースのパーサーの場合、パーサーは、パーサーのステートマシン内の可能なブランチのIDを含むイベントを発行すると推測しています。オートコンプリートモジュールは、そのような状態ごとに何を出力するかを認識します。

ツリーベースのパーサーの場合、パーサーは、使用可能なブランチを何らかの方法で含むツリー構造を返す必要があります。

これはどのように行われていますか?オートコンプリートが必要な場合、コマンド文字列の処理に最適なパーサーのタイプはどれですか。

4

1 に答える 1

8

LR(k)文法から先読みセット(つまり、受け入れ可能なトークンタイプ)を読み取ることができますが、そのような文法は巨大になる傾向があります。文法を圧縮するさまざまな形式(LALR(1)がおそらく最も一般的です)により、先読みセットの精度が低下します(常に有効なトークンタイプが含まれますが、無効なトークンタイプが含まれる場合もあります)。先読みセットの無効なトークンタイプは、テーブルの圧縮や、エラー生成(エラーメッセージを改善するために含まれる)を意図的に含めることによっても発生する可能性があります。

再帰下降パーサーから先読みセットを読み取るのは難しい場合があります。これは、そのようなパーサーは通常、遷移テーブルに依存するのではなく、オープンコード化されているためです。ただし、少なくとも理論的には、LL(k)文法には、先読みセットを計算する可能性もありますが、不正確であることが判明する場合もあります。

ただし、最も興味深いオートコンプリートは句読点ではなく記号です。文法は、特定の時点でスコープ内にある名前を示すのに十分ではありませんが、どのタイプの名前が実行可能であるかを示すことはできる場合があります。正確なオートコンプリート情報を取得するには、シンボルテーブルにフックする必要があります。宣言の前に識別子を使用できる言語では、パーサーが未解決の名前のリストをどこかに保持している可能性がありますが、これはさらに難しい場合があります。

パーサーを使用してオートコンプリート情報を生成する際のもう1つの問題は、構文的に正しいプログラム用にパーサーが最適化される傾向があり、構文エラーを検出した後はまったく機能しない可能性があることです。IDEユーザーにとって、これは本当に苛立たしいことです。マイナーな句読点エラーは、エラーが追跡されて修正されるまでオートコンプリートを無効にします。(個人的には、そのようなシステムはコードを書くにはあまりにも気が散ることに気づきました。コードの他の部分に括弧がないことよりも、現時点で書いていることに焦点を当てたいと思います。)

IM(H)O、packratの解析に漠然と似ているものを使用して、挿入ポイントでコンテキストを十分に抽出し、その後に続く可能性のある合理的な概念を取得することをお勧めします。正しいデータ型宣言を完了するためのアクセス権がある場合は、それらを使用しますが、シンボルのように見えるものを先読みセットに入れるというフォールバックが常にあります(ただし、それもイライラする可能性があります)。

とにかく頑張ってください。

于 2012-09-20T21:30:14.643 に答える