トークンの作り方がわからない
python製のテンプレートエンジンを作っていて、ifブロックを実装するときに昨日までは愚直に一行ずつ正規表現でマッチさせて、フラグを上げたり下げたりとかネストレベルを保持するカウンターの値を増やしたり減らしたりしてifブロック内のパースをしていたのだが、トークンに切り分けてやったほうが良いのではないかと気づいてトークンに分割するようにしてみた。
けど、全然うまくいかない。分割そのものは簡単だった。ただ、ifブロックのネストのこととかを考えると単純にいかなくなる。例えば下記みたいなのがあるとする。
{{ if hoge }} hogeのときだけ出力 {{ if fuga }} fugaのときだけ出力 {{ fi }} {{ fi }}
{{
、}}
とそれ以外をトークンにして分割すると、下記のようになる(見やすくするため、半角スペースは_
で書く。あと改行は\n
)。
{{ _if_hoge_ }} \n____hogeのときだけ出力\n____ {{ _if_fuga_ }} \n________fugaのときだけ出力\n____ {{ _fi_ }} \n {{ _fi_ }} \n
これをループで回してパースしたい。
ifとfiは単純に{{}}で囲まれているだけだから簡単にパースできる。
問題はifとfiの間のブロックで、ifブロックの中にある場合はそいつらだけ別の変数に入れて、別のメソッドでブロックの中をパースしたいわけだけど、どこからどこまでがifブロックかを判定する段階でif hoge
からif fuga
をも含めて最後のfi
までループを回してしまっている。
すると、ifブロックパース専用メソッドの中でまたifブロックをループでなめてパースするのは無駄だ。ループは一回で済ませたい。
トークンは文字列じゃなくてオブジェクトにして、トークンに分割した段階でifのネストレベル、forのネストレベルなどを持っておくべきなのか。。
自分の設計力の無さに唖然としている。明日はもう少し進展することを願いつつ今日は寝る。。