前の日 / 次の日 / 最新 / 2008-02

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

次は、字句解析器を書いてみようか

参考
テンプレート再訪