01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
2008-02-16 Sat
■ tokenizer [D言語]
コンパイル時に動作する tokenizer を作ってみた。
スペース区切りの文字列でしか動作しない。
ライセンス
NYSL Version 0.9982 に従います。
http://mikanya.dip.jp/repos/junk/meta/tokenizer.d
/++ + compile time tokenizer + + スペースで区切られた文字列を分割し、 + 結果をタプルで返す + + Authors: mikanya + Copyright: mikanya + License: NYSL Version 0.9982 + + Example: + ------------------------------------- + import std.stdio; + import meta.tokenizer; + + void main() + { + const char[] s = "this is a pen"; + alias Tokenizer!(s).tokens list; + + foreach(i;list) writefln(i); + + } + ------------------------------------- +/ module meta.tokenizer; template Tuple(E...) { alias E Tuple; } template Parse(const char[] src) { static if (src.length == 0) { const Parse = ""; } else static if (src[0] != ' ') { const Parse = src[0] ~ Parse!(src[1..$]); } else { const Parse = ""; } } template Tokenizer(const char[] src) { static if (src.length == 0) { alias Tuple!("") tokens; } else { const token = Parse!(src); static if(token.length == src.length) { const next = src[token.length .. $]; } else { const next = src[token.length + 1 .. $]; } alias Tuple!(TokenizerRecurse!(token,next).tokens) tokens; } } template TokenizerRecurse(const char[] tkn,const char[] src) { static if (src.length > 0) { alias Tokenizer!(src) next; alias Tuple!(tkn, next.tokens) tokens; } else { alias Tuple!(tkn) tokens; } }
こんな風に使う
import std.stdio; import meta.tokenizer; void main() { const char[] s = "this is a pen"; //foreach(i:Tokenizer!(s).tokens) writefln こう書くと、 //Assertion failure: '0' on line 4917 in file 'expression.c' //と出てコンパイルが通らない。 dmd2.010 alias Tokenizer!(s).tokens list; foreach(i;list) writefln(i); }
結果
this is a pen
次は、字句解析器を書いてみようか
参考
テンプレート再訪