Yash 2 その 278: 単語展開の過程の効率化
昨日の話の続き
データ構造を考へ直す前に、POSIX が定める展開の過程をおさらひしておく。
- 四種展開 (チルダ展開、パラメータ展開、コマンド置換、数式展開)
- 単語分割
- パス名展開
- 引用符除去
- 空単語除去
引用符除去と空単語除去は順序を逆にして考へた方が都合が良い。引用符で囲まれてゐない空単語を除去し、その後に引用符を除去すると考へた方が自然だからだ。
さて、単語分割と空単語・引用符除去の間にパス名展開がある。空単語や引用符の取り扱ひはパス名展開の処理において邪魔だ。なので、今の yash ではパス名展開の前に引用符をバックスラッシュに置換してしまってゐる。そしてそれが、引用符で囲まれた空単語とただの空単語を区別できなくなる原因であった。
引用符除去・空単語除去をパス名展開の前に持ってきてよいかを検討するために、もう少し深く考へてみよう。パス名展開で展開の対象となるのは、*
や ?
などのパターンを含んだ単語だけだ。よって、引用符の有無に関係なく空単語はパス名展開による影響を受けない。すなはち、空単語に対して引用符除去・空単語除去をパス名展開の前に行っても差し支へない。では空でない文字列のパス名展開はどうか。空文字列はファイル名として許されてゐないので、パス名展開の結果が空文字列になることは無い。従って空単語除去のことは無視できる。また yash ではパス名展開の前に引用符をバックスラッシュに置換するので、結果として引用符除去もパス名展開の前に行はれることになる。
まとめると、この様な流れになる。
空単語除去を単語分割の前に持ってくることはできない。非空文字列が単語分割によって空文字列になる場合があるので、その後の空単語除去で除去しないといけないからだ。
ブレース展開が有効な時は四種展開と単語分割の間にブレース展開を行ふことになる。ブレース展開を行ふタイミングは引用符除去・空単語除去より後にした方が実装が楽になってよいが、bash の動きに近付けるために単語分割前に行ふ。
| 固定リンク
コメント