見出し画像

FR2の字句解析と構文解析

どーも、どーも、こんばんわー、ハルキーです。
今日はゆるっと猫つく言語FR2のソースコードを載せていきたいと思います。

字句解析190行くらい、構文解析870行くらいです。
文字の組み合わせをLetterクラスで、単語にまとめた後、Localにブロック構造を格納していきます。

丁寧に見てもらうとわかるかもしれませんが、基本的に計算式を解析するコードと、行の組み合わせを解析するコードの2つしかないので、コピペに近い感じで作られているので、その気になれば、まだまだ行数を削れます。
(見にくくなるし、カスタマイズ性なくなるからしないけど。)

Compileが字句解析、Startからが構文解析です。
Feel,Result,ReasonOneはint x:, 1に該当し
Blockは()の中を調べる。
Reasonは:改行か、:式(ResultOne)を分けます。
Block2とBlock2_2は、{…|….}を処理しています。

簡単な説明はこんなもんで。

ブログで読むにはそれなりに長いコードなので、興味あったらどうぞみたいな感じで載せました。
しばらくしたら、GitHubにあげます。
4日後に意味解析のコードあげますね。

応援してくれると、うれしいです。
スキ、フォローよろしくお願いします。


        public void Compile(string text)
        {
            List<Letter> letters = new List<Letter>();
            var bk = 0;
            var row = 0;
            for (var i = 0; i < text.Length; i++)
            {
                if (('a' <= text[i] && text[i] <= 'z') || ('A' <= text[i] && text[i] <= 'Z'))
                {
                    var j = i + 1;
                    for (; j < text.Length; j++)
                    {
                        if (('a' <= text[j] && text[j] <= 'z') || ('A' <= text[j] && text[j] <= 'Z') || ('0' <= text[j] && text[j] <= '9')) continue;
                        break;
                    }
                    Letter l = new Letter() { name = text.Substring(i, j - i), type = LetterType.Letter, row = row };
                    letters.Add(l);
                    i = j - 1;
                }
                else if ('0' <= text[i] && text[i] <= '9')
                {
                    var j = i + 1;
                    for (; j < text.Length; j++)
                    {
                        if ('0' <= text[j] && text[j] <= '9') continue;
                        break;
                    }
                    letters.Add(new Letter() { name = text.Substring(i, j - i), type = LetterType.Number, row = row });
                    i = j - 1;
                }
                else if (text[i] == '"')
                {
                    var j = i + 1;
                    for(; j < text.Length; j++)
                    {
                        if (text[j] == '"')
                        {
                            letters.Add(new Letter() { name = text.Substring(i + 1, j - i - 1), type = LetterType.Str, row = row });
                            break;
                        }
                    }
                    i = j;
                }
                else if (text[i] == ':')
                {
                    letters.Add(new Letter() { type = LetterType.Colon, row = row });
                }
                else if (text[i] == '=')
                {
                    if (i + 1 < text.Length && text[i + 1] == '=')
                    {
                        i++;
                        letters.Add(new Letter() {name = "==", type = LetterType.Operator, row = row });
                    }
                    else letters.Add(new Letter() { type = LetterType.Colon, row = row });
                }
                else if (text[i] == ';')
                {
                    letters.Add(new Letter() { type = LetterType.Semicolon, row = row });
                }
                else if (text[i] == ',')
                {
                    letters.Add(new Letter() { type = LetterType.Comma, row = row });
                }
                else if (text[i] == '|')
                {
                    letters.Add(new Letter() { type = LetterType.Bou, row = row });
                }
                else if (text[i] == '#')
                {
                    letters.Add(new Letter() { type = LetterType.Sharp, row = row });
                }
                else if (text[i] == '@')
                {
                    var j = i + 1;
                    if (('a' <= text[j] && text[j] <= 'z') || ('A' <= text[j] && text[j] <= 'Z'))
                    {
                        j++;
                        for (; j < text.Length; j++)
                        {
                            if (('a' <= text[j] && text[j] <= 'z') || ('A' <= text[j] && text[j] <= 'Z')) continue;
                            break;
                        }
                        letters.Add(new Letter() { name = text.Substring(i, j - i), type = LetterType.AtLetter, row = row });
                        i = j - 1;
                    }
                }
                else if (text[i] == '\n')
                {
                    i++;
                    var count = 0;
                    for (; i < text.Length; i++)
                    {
                        if (text[i] == ' ') count++;
                        else if (text[i] == '\n') count = 0;
                        else break;
                    }
                    i--;
                    letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.Kaigyou, indent = count, row = row });
                    row++;
                }
                else if (text[i] == '+')
                {
                    letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.Plus, row = row });
                }
                else if (text[i] == '-')
                {
                    if (i != 0 && i + 1 < text.Length && text[i - 1] == ' ' && text[i + 1] != ' ')
                    {
                        letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.SingleMinus, row = row });
                    }
                    else {
                        letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.Minus, row = row });
                    }
                }
                else if (text[i] == '<')
                {
                    if (i + 1 < text.Length)
                    {
                        if (text[i + 1] == '-')
                        {
                            letters.Add(new Letter() { name = "<-", type = LetterType.Left, row = row });
                            i++;
                        }
                        else if (text[i + 1] == '=')
                        {
                            letters.Add(new Letter() { name = text.Substring(i, 2), type = LetterType.LessEqual, row = row });
                            i++;
                        }
                        else letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.LessThan, row = row });
                    }
                    else letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.LessThan, row = row });
                }
                else if (text[i] == '>')
                {
                    if (i + 1 < text.Length && text[i + 1] == '=')
                    {
                        letters.Add(new Letter() { name = text.Substring(i, 2), type = LetterType.MoreEqual, row = row });
                        i++;
                    }
                    else letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.MoreThan, row = row });
                }
                else if (text[i] == '*')
                {
                    letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.Mul, row = row });
                }
                else if (text[i] == '/')
                {
                    letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.Div, row = row });
                }
                else if (text[i] == '|')
                {
                    letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.Bou, row = row });
                }
                else if (text[i] == '.')
                {
                    letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.Dot, row = row });
                }
                else if (text[i] == '(')
                {
                    letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.BracketS, row = row });
                }
                else if (text[i] == ')')
                {
                    letters.Add(new Letter() { name = text[i].ToString(), type = LetterType.BracketE, row = row });
                }
                else if (text[i] == '[')
                {
                    letters.Add(new Letter() { type = LetterType.BlockS, row = row });
                }
                else if (text[i] == ']')
                {
                    letters.Add(new Letter() { type = LetterType.BlockE, row = row });
                }
                else if (text[i] == '{')
                {
                    letters.Add(new Letter() { type = LetterType.BraceS, row = row });
                }
                else if (text[i] == '}')
                {
                    letters.Add(new Letter() { type = LetterType.BraceE, row = row });
                }
            }
            letters.Add(new Letter() { type = LetterType.End, row = row });
            Local local = new Local() { letters = letters, n = 0, console=console };
            Start(local);
            local.exe(local, null);
            local.startDecExe();
        }
        void Start(Local local)
        {
            for (; ; )
            {
                if (local.letter.type == LetterType.Kaigyou)
                {
                    if (local.indent == local.letter.indent)
                    {
                        local.NextLine();
                        local.plus(1);
                    }
                    else if (local.indent > local.letter.indent)
                    {
                        throw new Exception();
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
                else if (local.letter.type == LetterType.Semicolon)
                {
                    local.NextLine();
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Sharp)
                {
                    local.plus(1);
                    if (local.letter.type == LetterType.Letter)
                    {
                        local.label(local.letter.name);
                        local.plus(1);
                    }
                    else if (local.letter.type == LetterType.Number)
                    {
                        local.label(Convert.ToInt32(local.letter.name).ToString());
                        local.plus(1);
                    }
                    else if (local.letter.type == LetterType.Str)
                    {
                        local.label(local.letter.name);
                        local.plus(1);
                    }
                    else local.label("");
                }
                else if (local.letter.type == LetterType.End)
                {
                    return;
                }
                else
                {

                    Feel(local, LetterType.Kaigyou);
                }
            }
        }
        void Feel(Local local, LetterType finish)
        {
            for (; ; )
            {
            head:
                if (local.letter.type == LetterType.Minus || local.letter.type == LetterType.SingleMinus)
                {
                    local.feeladd(new Item(LetterType.SingleMinus) { order = 1 });
                    local.plus(1);
                }
                if (local.letter.type == LetterType.BracketS)
                {
                    local.plus(1);
                    var ar2 = new Array();
                    local.feeladd(new Item(LetterType.Array) { obj = ar2, order = 0 });
                    Block(local, ar2, LetterType.BracketE);
                }
                else if (local.letter.type == LetterType.Letter)
                {
                    local.feeladd(new Item(LetterType.Letter) { name = local.letter.name }.Letter(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Number)
                {
                    local.feeladd(new Item(LetterType.Number) { name = local.letter.name }.Number(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Str)
                {
                    local.feeladd(new Item(LetterType.Str) { name = local.letter.name }.StrObj(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Kaigyou)
                {
                    local.plus(1);
                    goto head;
                }
                else
                {
                    throw new Exception();
                }
            bl:
                if (local.letter.type == LetterType.BlockS)
                {
                    var ar2 = new Array();
                    local.feeldraw(new Item(LetterType.Array) { obj = ar2 });
                    local.plus(1);
                    Block(local, ar2, LetterType.BlockE);
                    goto bl;
                }
                else if (local.letter.type == LetterType.BraceS)
                {
                    var call = new Call();
                    local.feeldraw(new Item(LetterType.Call) { obj = call });
                    local.plus(1);
                    Block2(local, call);
                    goto bl;
                }
                if (local.letter.type == LetterType.Letter)
                {
                    Result(local, finish);
                    return;
                }
                if (local.letter.type == LetterType.Number || local.letter.type == LetterType.Str)
                {
                    Result(local, finish);
                    return;
                }
                else if (local.letter.type == LetterType.BracketS)
                {
                    Result(local, finish);
                    return;
                }
                else if (local.letter.type == LetterType.Left)
                {
                    local.feeladd(new Item(LetterType.Left) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Dot)
                {
                    local.feeladd(new Item(LetterType.Dot) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Comma)
                {
                    local.feelnext();
                    local.plus(1);
                }
                else if (LetterType.Plus <= local.letter.type && local.letter.type <= LetterType.Operator)
                {
                    switch (local.letter.type)
                    {
                        case LetterType.Plus: case LetterType.Minus:
                            local.feeladd(new Item(local.letter.type) { name = local.letter.name, order = 10 });
                            break;
                        case LetterType.Mul: case LetterType.Div:
                            local.feeladd(new Item(local.letter.type) { name = local.letter.name, order = 9 });
                            break;
                        case LetterType.LessThan: case LetterType.MoreThan: case LetterType.LessEqual: case LetterType.MoreEqual: case LetterType.EqualEqual:
                            local.feeladd(new Item(local.letter.type) { name = local.letter.name, order = 14 });
                            break;
                    }
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Colon)
                {
                    local.block.line.result = local.block.line.feel;
                    local.block.line.feel = null;
                    local.plus(1);
                    Reason(local, finish);
                    return;
                }
                else if (local.letter.type == LetterType.Semicolon)
                {
                    local.block.line.reason = local.block.line.feel;
                    local.block.line.feel = null;
                    return;
                }
                else if (local.letter.type == finish)
                {
                    local.block.line.reason = local.block.line.feel;
                    local.block.line.feel = null;
                    return;
                }
                else if (local.letter.type == LetterType.End)
                {
                    local.block.line.reason = local.block.line.feel;
                    local.block.line.feel = null;
                    return;
                }
                else
                {
                    throw new Exception();
                }
            }
        }
        void Block(Local local, Array ar, LetterType end)
        {
            if (local.letter.type == end)
            {
                local.plus(1);
                return;
            }
            else if (local.letter.type == LetterType.Sharp)
            {
                local.plus(1);
                if (local.letter.type == LetterType.Letter)
                {
                    ar.label(local.letter.name);
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Number)
                {
                    ar.label(Convert.ToInt32(local.letter.name).ToString());
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Str)
                {
                    ar.label(local.letter.name);
                    local.plus(1);
                }
                else ar.label("");
            }
            for (; ; )
            {
            head:
                if (local.letter.type == LetterType.Minus || local.letter.type == LetterType.SingleMinus)
                {
                    ar.add(new Item(LetterType.SingleMinus) { order = 1});
                    local.plus(1);
                }
                if (local.letter.type == LetterType.BracketS)
                {
                    local.plus(1);
                    var ar2 = new Array();
                    ar.add(new Item(LetterType.Array) { obj = ar2, order = 0 });
                    Block(local, ar2, LetterType.BracketE);
                }
                else if (local.letter.type == LetterType.Letter)
                {
                    ar.add(new Item(LetterType.Letter) { name = local.letter.name }.Letter(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Number)
                {
                    ar.add(new Item(LetterType.Number) { name = local.letter.name }.Number(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Str)
                {
                    ar.add(new Item(LetterType.Str) { name = local.letter.name }.StrObj(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Kaigyou)
                {
                    local.plus(1);
                    goto head;
                }
                else
                {
                    throw new Exception();
                }
            bl:
                if (local.letter.type == LetterType.BlockS)
                {
                    var ar2 = new Array();
                    ar.addfunc(new Item(LetterType.Array) { obj = ar2 });
                    local.plus(1);
                    Block(local, ar2, LetterType.BlockE);
                    goto bl;
                }
                else if (local.letter.type == LetterType.BraceS)
                {
                    local.plus(1);
                    var call = new Call(); 
                    ar.addfunc(new Item(LetterType.Call) { obj =call });
                    Block2(local, call);
                    goto bl;
                }
                if (local.letter.type == LetterType.Letter || local.letter.type == LetterType.BracketS)
                {
                    throw new Exception();
                }
                else if (local.letter.type == LetterType.Left)
                {

                    ar.add(new Item(LetterType.Left) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Dot)
                {
                    ar.add(new Item(LetterType.Dot) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Comma)
                {
                    ar.next();
                    local.plus(1);
                    if (local.letter.type == LetterType.Sharp)
                    {
                        local.plus(1);
                        if (local.letter.type == LetterType.Letter)
                        {
                            ar.label(local.letter.name);
                            local.plus(1);
                        }
                        else if (local.letter.type == LetterType.Number)
                        {
                            ar.label(Convert.ToInt32(local.letter.name).ToString());
                            local.plus(1);
                        }
                        else if (local.letter.type == LetterType.Str)
                        {
                            ar.label(local.letter.name);
                            local.plus(1);
                        }
                        else ar.label("");
                    }
                }
                else if (LetterType.Plus <= local.letter.type && local.letter.type <= LetterType.SingleMinus)
                {
                    switch (local.letter.type)
                    {
                        case LetterType.SingleMinus:
                            ar.add(new Item(LetterType.Minus) { name = local.letter.name, order = 10 });
                            break;
                        case LetterType.Plus: case LetterType.Minus:
                            ar.add(new Item(local.letter.type) { name = local.letter.name, order = 10 });
                            break;
                        case LetterType.Mul: case LetterType.Div:
                            ar.add(new Item(local.letter.type) { name = local.letter.name, order = 9 });
                            break;
                        case LetterType.LessThan: case LetterType.MoreThan: case LetterType.LessEqual: case LetterType.MoreEqual: case LetterType.EqualEqual:
                            ar.add(new Item(local.letter.type) { name = local.letter.name, order = 14 });
                            break;
                    }
                    local.plus(1);
                }
                else if (local.letter.type == end)
                {
                    local.plus(1);
                    return;
                }
                else if (local.letter.type == LetterType.Kaigyou)
                {
                    throw new Exception();
                }
                else if (local.letter.type == LetterType.End)
                {
                    throw new Exception();
                }
                else
                {
                    throw new Exception();
                }
            }
        }
        void Result(Local local, LetterType finish)
        {
            for (; ; )
            {
            head:
                if (local.letter.type == LetterType.SingleMinus || local.letter.type == LetterType.Minus)
                {
                    local.resultadd(new Item(LetterType.SingleMinus) { order = 1 });
                    local.plus(1);
                }
                if (local.letter.type == LetterType.BracketS)
                {
                    local.plus(1);
                    var ar2 = new Array();
                    local.resultadd(new Item(LetterType.Array) { obj = ar2, order = 0 });
                    Block(local, ar2, LetterType.BracketE);
                }
                else if (local.letter.type == LetterType.Letter)
                {
                    local.resultadd(new Item(LetterType.Letter) { name = local.letter.name }.Letter(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Number)
                {
                    local.resultadd(new Item(LetterType.Number) { name = local.letter.name }.Number(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Str)
                {
                    local.resultadd(new Item(LetterType.Str) { name = local.letter.name }.StrObj(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Kaigyou)
                {
                    local.plus(1);
                    goto head;
                }
                else
                {
                    throw new Exception();
                }
            bl:
                if (local.letter.type == LetterType.BlockS)
                {
                    var ar2 = new Array();
                    local.resultdraw(new Item(LetterType.Array) { obj = ar2 });
                    local.plus(1);
                    Block(local, ar2, LetterType.BlockE);
                    goto bl;
                }
                else if (local.letter.type == LetterType.BraceS)
                {
                    var call = new Call();
                    local.resultdraw(new Item(LetterType.Call) { obj = call });
                    local.plus(1);
                    Block2(local, call);
                    goto bl;
                }
                if (local.letter.type == LetterType.Comma)
                {
                    local.plus(1);
                }
                else if (LetterType.Plus <= local.letter.type && local.letter.type <= LetterType.SingleMinus)
                {
                    switch (local.letter.type)
                    {
                        case LetterType.SingleMinus:
                            local.resultadd(new Item(LetterType.Minus) { name = local.letter.name, order = 10 });
                            break;
                        case LetterType.Plus: case LetterType.Minus:
                            local.resultadd(new Item(local.letter.type) { name = local.letter.name, order = 10 });
                            break;
                        case LetterType.Mul: case LetterType.Div:
                            local.resultadd(new Item(local.letter.type) { name = local.letter.name, order = 9 });
                            break;
                        case LetterType.LessThan: case LetterType.MoreThan: case LetterType.LessEqual: case LetterType.MoreEqual: case LetterType.EqualEqual:
                            local.resultadd(new Item(local.letter.type) { name = local.letter.name, order = 14 });
                            break;
                    }
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Left)
                {
                    local.resultadd(new Item(LetterType.Left) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Dot)
                {
                    local.resultadd(new Item(LetterType.Dot) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Colon)
                {
                    local.plus(1);
                    Reason(local, finish);
                    return;
                }
                else if (local.letter.type == LetterType.Semicolon)
                {
                    return;
                }
                else if (local.letter.type == finish)
                {
                    return;
                }
                else if (local.letter.type == LetterType.End)
                {
                    return;
                }
                else
                {
                    throw new Exception();
                }
            }
        }
        void Block2(Local local, Call call)
        {
            local.CallBlock(call);
            if (local.lettersearch([LetterType.Semicolon, LetterType.BraceE, LetterType.Kaigyou], [LetterType.Bou]))
            {
                local.Call2Block(call);
                Block2_2(local);
                return;
            }
            if (local.letter.type == LetterType.Bou)
            {
                local.plus(1);
                local.Call2Block(call);
                Block2_2(local);
                return;
            }
            for (; ; )
            {
            head:
                if (local.letter.type == LetterType.BracketS)
                {
                    local.plus(1);
                    var ar2 = new Array();
                    local.feeladd(new Item(LetterType.Array) { obj = ar2, order = 0 });
                    Block(local, ar2, LetterType.BracketE);
                }
                else if (local.letter.type == LetterType.Letter)
                {
                    local.feeladd(new Item(LetterType.Letter) { name = local.letter.name }.Letter(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Kaigyou)
                {
                    local.plus(1);
                    goto head;
                }
                else throw new Exception();
                head2:
                if (local.letter.type == LetterType.Letter)
                {
                    local.resultadd(new Item(LetterType.Letter) { name = local.letter.name }.Letter(local));
                    local.plus(1);
                head3:
                    if (local.letter.type == LetterType.Comma)
                    {
                        local.NextLine();
                        local.plus(1);
                        goto head;
                    }
                    else if (local.letter.type == LetterType.Bou)
                    {
                        local.plus(1);
                        local.Call2Block(call);
                        Block2_2(local);
                        return;
                    }
                    else if (local.letter.type == LetterType.BraceE)
                    {
                        local.CallFinish();
                        local.plus(1);
                        return;
                    }
                    else if (local.letter.type == LetterType.Kaigyou)
                    {
                        local.plus(1);
                        goto head3;
                    }
                    else throw new Exception();
                }
                else if (local.letter.type == LetterType.Left)
                {
                    local.feeladd(new Item(LetterType.Left) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Dot)
                {
                    local.feeladd(new Item(LetterType.Dot) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Kaigyou)
                {
                    local.plus(1);
                    goto head2;
                }
                else throw new Exception();
            }
        }
        void Block2_2(Local local)
        {
            if (local.letter.type == LetterType.Kaigyou)
            {
                if (local.indent == local.letter.indent)
                {
                    throw new Exception();
                }
                else if (local.indent > local.letter.indent)
                {
                    throw new Exception();
                }
                else
                {
                    local.Call2Indent(local.letter.indent);
                }
                local.plus(1);
                for (; ; )
                {
                    if (local.letter.type == LetterType.Kaigyou)
                    {
                        if (local.indent == local.letter.indent)
                        {
                            local.NextLine();
                            local.plus(1);
                        }
                        else if (local.indent > local.letter.indent)
                        {
                            local.plus(1);
                            if (local.letter.type == LetterType.BraceE)
                            {
                                local.CallFinish();
                                local.CallIndentFinish();
                                local.plus(1);
                                return;
                            }
                            else throw new Exception();
                        }
                        else
                        {
                            throw new Exception();
                        }
                    }
                    else if (local.letter.type == LetterType.Sharp)
                    {
                        local.plus(1);
                        if (local.letter.type == LetterType.Letter)
                        {
                            local.label(local.letter.name);
                            local.plus(1);
                        }
                        else if (local.letter.type == LetterType.Number)
                        {
                            local.label(local.letter.name);
                            local.plus(1);
                        }
                        else if (local.letter.type == LetterType.Str)
                        {
                            local.label(local.letter.name);
                            local.plus(1);
                        }
                        else local.label("");
                    }
                    else if (local.letter.type == LetterType.Semicolon)
                    {
                        local.NextLine();
                        local.plus(1);
                    }
                    else if (local.letter.type == LetterType.BraceE)
                    {
                        local.CallFinish();
                        local.CallIndentFinish();
                        local.plus(1);
                        return;
                    }
                    else if (local.letter.type == LetterType.End)
                    {
                        throw new Exception();
                    }
                    else
                    {

                        Feel(local, LetterType.Kaigyou);
                    }
                }
            }
            else if (local.letter.type == LetterType.End)
            {
                return;
            }
            else
            {
                for (; ; )
                {
                    if (local.letter.type == LetterType.BraceE)
                    {
                        local.plus(1);
                        local.CallFinish();
                        return;
                    }
                    else if (local.letter.type == LetterType.Semicolon)
                    {
                        local.plus(1);
                        local.NextLine();
                    }
                    else if (local.letter.type == LetterType.Sharp)
                    {
                        local.plus(1);
                        if (local.letter.type == LetterType.Letter)
                        {
                            local.label(local.letter.name);
                            local.plus(1);
                        }
                        else local.label("");
                    }
                    else if (local.letter.type == LetterType.Kaigyou) throw new Exception();
                    else Feel(local, LetterType.BraceE);
                }
            }
        }
        void Reason(Local local, LetterType finish)
        {
            if (local.letter.type == LetterType.Kaigyou)
            {
                if (local.indent == local.letter.indent)
                {
                    local.NextLine();
                    local.plus(1);
                    return;
                }
                else if (local.indent > local.letter.indent)
                {
                    return;
                }
                else
                {
                    local.NextLine();
                    local.StartBlock(local.letter.indent);
                }
                local.plus(1);
                for (; ; )
                {
                    if (local.letter.type == LetterType.Kaigyou)
                    {
                        if (local.indent == local.letter.indent)
                        {
                            local.NextLine();
                            local.plus(1);
                        }
                        else if (local.indent > local.letter.indent)
                        {
                            local.FinishBlock();
                            local.NextLine();
                            return;
                        }
                        else
                        {
                            throw new Exception();
                        }
                    }
                    else if (local.letter.type == LetterType.Sharp)
                    {
                        local.plus(1);
                        if (local.letter.type == LetterType.Letter)
                        {
                            local.label(local.letter.name);
                            local.plus(1);
                        }
                        else if (local.letter.type == LetterType.Number)
                        {
                            local.label(Convert.ToInt32(local.letter.name).ToString());
                            local.plus(1);
                        }
                        else if (local.letter.type == LetterType.Str)
                        {
                            local.label(local.letter.name);
                            local.plus(1);
                        }
                        else local.label("");
                    }
                    else if (local.letter.type == LetterType.Semicolon)
                    {
                        local.NextLine();
                        local.plus(1);
                    }
                    else if (local.letter.type == LetterType.End)
                    {
                        return;
                    }
                    else
                    {

                        Feel(local, LetterType.Kaigyou);
                    }
                }
            }
            else if (local.letter.type == LetterType.End)
            {
                return;
            }
            else
            {
                ReasonOne(local, finish);
                return;
            }
        }
        void ReasonOne(Local local, LetterType finish)
        {
            for (; ; )
            {
            head:
                if (local.letter.type == LetterType.SingleMinus || local.letter.type == LetterType.Minus)
                {
                    local.reasonadd(new Item(LetterType.SingleMinus) { order = 1 });
                    local.plus(1);
                }
                if (local.letter.type == LetterType.BracketS)
                {
                    local.plus(1);
                    var ar2 = new Array();
                    local.reasonadd(new Item(LetterType.Array) { obj = ar2, order = 0 });
                    Block(local, ar2, LetterType.BracketE);
                }
                else if (local.letter.type == LetterType.Letter)
                {
                    local.reasonadd(new Item(LetterType.Letter) { name = local.letter.name }.Letter(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Number)
                {
                    local.reasonadd(new Item(LetterType.Number) { name = local.letter.name }.Number(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Str)
                {
                    local.reasonadd(new Item(LetterType.Str) { name = local.letter.name }.StrObj(local));
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Kaigyou)
                {
                    local.plus(1);
                    goto head;
                }
                else
                {
                    throw new Exception();
                }
            bl:
                if (local.letter.type == LetterType.BlockS)
                {
                    var ar2 = new Array();
                    local.reasondraw(new Item(LetterType.Array) { obj = ar2 });
                    local.plus(1);
                    Block(local, ar2, LetterType.BlockE);
                    goto bl;
                }
                else if (local.letter.type == LetterType.BraceS)
                {
                    var call = new Call();
                    local.reasondraw(new Item(LetterType.Call) { obj = call });
                    local.plus(1);
                    Block2(local, call);
                    goto bl;
                }
                if (local.letter.type == LetterType.Comma)
                {
                    local.plus(1);
                }
                else if (LetterType.Plus <= local.letter.type && local.letter.type <= LetterType.SingleMinus)
                {
                    switch (local.letter.type)
                    {
                        case LetterType.SingleMinus:
                            local.reasonadd(new Item(LetterType.Minus) { name = local.letter.name, order = 10 });
                            break;
                        case LetterType.Plus: case LetterType.Minus:
                            local.reasonadd(new Item(local.letter.type) { name = local.letter.name, order = 10 });
                            break;
                        case LetterType.Mul: case LetterType.Div:
                            local.reasonadd(new Item(local.letter.type) { name = local.letter.name, order = 9 });
                            break;
                        case LetterType.LessThan: case LetterType.MoreThan: case LetterType.LessEqual: case LetterType.MoreEqual: case LetterType.EqualEqual:
                            local.reasonadd(new Item(local.letter.type) { name = local.letter.name, order = 14 });
                            break;
                    }
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Left)
                {

                    local.reasonadd(new Item(LetterType.Left) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Dot)
                {
                    local.reasonadd(new Item(LetterType.Dot) { name = local.letter.name, order = 1 });
                    local.plus(1);
                }
                else if (local.letter.type == LetterType.Semicolon)
                {
                    return;
                }
                else if (local.letter.type == finish)
                {
                    return;
                }
                else if (local.letter.type == LetterType.End)
                {
                    return;
                }
                else
                {
                    throw new Exception();
                }
            }
        }

この記事が気に入ったらサポートをしてみませんか?