Query Parser

手続き言語系のコンパイラは一通り勉強したつもりだけど、構文解析器系は知識が甘いなと実感。特に構文エラー検出と回復関係が。
オートコンプリートの推論とかどうやってやるんだろ… Single token insertionとかで実現できるのかな…

以下メモ。

case1:.modから候補出して[.mod]ifierとしたいところ。

/**
 * @when
 *     public in target.mod(caret)
 *     hoge = foo.bar
 */

この場合、target.modまで書きこんであって、その直後を補完したいということが判明。modの末尾にキャレットが来ていることを記憶して、そのまま意味解析を行ってしまえばよさげ。

おそらく、".mod"というプロパティが存在しないというエラーになるので、そのプロパティがキャレットマーク付いていることから、"mod"から始まる候補の一覧を検出し、キャレット位置に挿入すればよい。

case2:構文エラーであるが[.]modifierとしたいところ。

/**
 * @when
 *     public in target.(caret)
 *     hoge = foo.bar
 */

「public in target . hoge = foo . bar」という列。推測が大変だ。

  • x "public in target.hoge", "missing = foo.bar"
  • o "public in target.missing", "hoge = foo.bar"
  • x "public in target.hoge =(typo). foo.bar"

構文解析がオートコンプリートにより呼び出され、かつ構文エラーならキャレット位置に0文字幅のダミートークンを補完するとかかな。キャレットを表すトークンを入れて、無理やり構文エラーにして回復の推測をするのもアリ。

こちらも、".(caret)"というプロパティが存在しないというエラーになるはず。あとは同じで。

まとめ

  1. オートコンプリート時はとりあえず通常の方法で構文解析
  2. エラーならキャレット位置にキャレットを表す擬似トークンを追加してもう一度 (single token insertion)
    1. キャレットトークンは構文上に出現しないので、確実にエラー。
    2. キャレットトークンを文法に沿ったトークン種に変更 (single token modification)
  3. キャレットの直前に存在するトークンを検出
  4. トークンの周辺を意味解析
  5. そのトークンの本来あるべき姿を検出


遠い。けど、方向性としてはこんなもんかしら。