sakura
sakura copied to clipboard
構文解析に外部ライブラリを使うように変更したい
(必須) やりたいこと(=実現したいこと)
構文解析に外部ライブラリを採用することにより、 コード中の構文解析のルールが分かるようにしたいです。
背景事情
サクラエディタには、入力されたテキストを解析してプログラムで利用できるカタチに変換する処理(以下、構文解析)がいくつか存在します。文字配列のインデックス操作と文字列操作のCランタイムルーチンによる自前実装なので、何をしているか読み取りづらくなっています。
主要な構文解析
- コマンドライン sakura.exe に渡されたコマンドラインからファイル名とオプションを解析しています。
- 設定ファイル sakura.iniから設定値を解析しています。
- ウインドウキャプション設定 タイトルバーに表示する文字列の設定を解析します。
- タブバーキャプション設定 タブバーに表示する文字列の設定を解析します。
- メインメニュー設定 リソースに埋め込まれたファイルから設定を解析します。
他にもあります。。。 Grepのファイル名指定やバックアップファイル名なんかも、実質的に構文解析してるかと思います。
(省略可) 解決手段の提案
構文解析ライブラリ Boost::Spirit
の採用を提案します。
ライブラリを使えば、先に構文規則を決めてルールベースで入力を処理するスタイルに転換できると思います。 構文解析をライブラリに任せることにより「構文に従わない入力」をどうするか、マジメに考えられるようになります。 現状は「構文に従わない入力」を読み捨てていて、読み捨てたことを教えてくれない実装になっています。
読めなかったら教えてくれたほうが嬉しい。 と個人的には思うので、是非外部ライブラリを採用したいです。
テキストエディタの構文解析で最近使われてるのは Tree-sitter とかみたいです。
要件的にはある程度大きい文書の解析をやってもUIが固まらない事が求められそうですね。
追記:ちゃんと説明文読んでなかったんですが、テキストエディタ部分ではなくてそれ以外の部分の解析処理なんですね。
外部ライブラリの適用先としては 2Kbytes未満 の小さいテキストの解析を想定していましたが、 エディタ本体への適用も「不可能ではない」と考えています。
■エディタ本体への適用が難しい理由
- プログラム言語でない「ただのテキスト」に「構文」を定義するのは難しい。
- 「表示範囲のみ」など「ドキュメントの一部」に対してレイアウト解析する機能があまり使われていないので、最大2G文字分を一括で解析できる仕組みが必要(不可能だと思います。)
- 時間のかかる処理の一部をワーカースレッドで実行させる仕組みがないので、UI操作に対してごく短い時間で応答しなければならず、構文解析のような処理に向かない。
色々課題はあるにしろ「解決できなくはない課題」だと思うので「不可能ではない」になります。
C++11の前までは自分もboostを使っていたんですが、最近は使っておらず良く分かりません。
Boost.Spirit
を採用するとなると submodule で boost 本体を追加するのでしょうか?
サクラエディタをビルドする際に外部ライブラリが必要な形になると思うので少し抵抗はあります。
導入イメージを持ちやすくするために、検証中ブランチをpushしてみました。
自分も最近はあまり触っていないので、実はそれほど詳しくないです。
ちなみに、 コマンドライン解析だけを対象とするならboost::program_optionsという選択もあると思ってます。→解説ページ
boost::program_options
はUNIX系のgetopt
のBoost版にあたるものです。
コマンドラインオプションを扱うためのライブラリとしては本来こっちなはずです。サクラエディタがもしCUIツールであったなら、こっちを推したかもしれないです。
boost::spirit
はUNIX系の lex + yacc(=flex + bison)
のBoost版にあたるものです。
サクラエディタのコマンドライン解析には、「構文解析」よりも下位レベルの「字句解析」が必要な気がしているので、こちらでないと移植できないのではないかと思ってます。
字句解析に限定するなら re2c
で関数作った方が軽量だと思いますよ。
ライブラリの依存関係をたくさん追加するとビルドのお手軽さが減ってしまう点に抵抗感があります。