演算子の優先順位を可視化したい
演算子の優先順位は難しい。当然 + * くらいはわかるのだが、 ^ | == << 等が入ってくるとややこしい。
C++ で個人的に非直感的な例:
a & b == c は a & (b == c)
a << b + c は a << (b + c)
恐ろしいことにこれは言語によって異なることがあり、例えば Go だと
a & b == c は (a & b) == c
a << b + c は (a << b) + c
となる。
ということで C++ で使える以下のような extension を作っている
https://gyazo.com/afb5d07502d37ea7a1e1ec4d7d015b7c
流れ:
VS Code の API でカーソルの行を取得
その行のコードを構文木にパースする
が、左結合演算子の一部しか紹介されていないのでまだまだ足りない
構文木では各トークンの位置を持っておき、カーソルの位置に相当するトークンを探索
そのトークンの左オペランドと右オペランドの範囲を探索
その範囲を装飾
理想への TODO(やるとは言っていない):
右結合演算子・単項演算子のサポート
右結合演算子について、例えば現状 a = b = c を (a = b) = c のように表示してしまうが、これは右結合演算子なので a = (b = c) のように表示しなければならない
入力途中でも(i.e. 全体として構文木に適切にパースできない状態でも)その前の箇所までパースし可視化できるようにする
前の行・次の行も良い感じに見る
コード全体をパースするとすれば単純だが、当然式以外のパーサを整備しなくてはならなくなるためやりたくないし処理としても無駄がある。式パーサだけでやっていくとすると、あるトークンが式の一部であるかどうかを前・後ろから連続的に判定できるようにする必要がある(できるのか?)
どれも難しい。
結論:コンパイラは凄い。