Kecaknoah.Analyze.KecaknoahLexer.AnalyzeFromText C# (CSharp) Method

AnalyzeFromText() private method

ソース名とソースを指定して解析します。
private AnalyzeFromText ( string name, string source ) : Kecaknoah.Analyze.KecaknoahLexResult
name string ソース名
source string 解析対象のソースコード
return Kecaknoah.Analyze.KecaknoahLexResult
        private KecaknoahLexResult AnalyzeFromText(string name, string source)
        {
            var result = new KecaknoahLexResult(name);
            var line = 0;
            var col = 0;
            var cq = "";
            Tuple<string, KecaknoahTokenType> kw;
            Match lm;
            KecaknoahError ei;
            while (source != "")
            {
                //空白論理行

                if (source.StartsWith(Environment.NewLine))
                {
                    source = source.Substring(Environment.NewLine.Length);
                    result.AddToken(new KecaknoahToken { Position = new Tuple<int, int>(line, col), TokenString = "<NewLine>", Type = KecaknoahTokenType.NewLine });
                    line++;
                    col = 0;
                    continue;
                }
                /*
                if (source.StartsWith(";"))
                {
                    source = source.Substring(1);
                    result.AddToken(new KecaknoahToken { Position = new Tuple<int, int>(line, col), TokenString = ";", Type = KecaknoahTokenType.Semicolon });
                    col++;
                    continue;
                }
                */
                Tuple<string, string> mcq = null;
                if ((mcq = MultilineCommentQuotations.FirstOrDefault(p => source.StartsWith(p.Item1))) != null)
                {
                    source = source.Substring(mcq.Item1.Length);
                    col += mcq.Item1.Length;
                    var ce = source.IndexOf(mcq.Item2);
                    var ecs = source.IndexOf(mcq.Item1);
                    //不正な複数行コメント
                    if ((ecs >= 0 && ecs < ce) || ce < 0)
                    {
                        ei = new KecaknoahError
                        {
                            Column = col,
                            Line = line,
                            Message = "不正な複数行コメントです。コメントが終了していないか、入れ子になっています。"
                        };
                        result.Error = ei;
                        result.Success = false;
                        return result;
                    }
                    while (true)
                    {
                        ce = source.IndexOf(mcq.Item2);
                        var cl = source.IndexOf(Environment.NewLine);
                        if ((cl > 0 && ce < cl) || cl < 0)
                        {
                            source = source.Substring(ce + mcq.Item2.Length);
                            col += ce + mcq.Item2.Length;
                            break;
                        }
                        else
                        {
                            source = source.Substring(cl + Environment.NewLine.Length);
                            line++;
                            col = 0;
                        }
                    }
                    continue;
                }
                //コメント
                if ((cq = LineCommentStart.FirstOrDefault(p => source.StartsWith(p))) != null)
                {
                    source = source.Substring(cq.Length);
                    col += cq.Length;
                    var cl = source.IndexOf(Environment.NewLine);
                    if (cl >= 0)
                    {
                        source = source.Substring(cl + Environment.NewLine.Length);
                        line++;
                        col = 0;
                    }
                    else
                    {
                        //ラストコメント
                        source = "";
                    }
                    continue;
                }
                //空白
                if ((lm = WhitespacePattern.Match(source)).Success && lm.Index == 0)
                {
                    source = source.Substring(lm.Length);
                    col += lm.Length;
                    continue;
                }
                //演算子
                if ((kw = Operators.FirstOrDefault(p => source.StartsWith(p.Item1))) != null)
                {
                    source = source.Substring(kw.Item1.Length);
                    col += kw.Item1.Length;
                    result.AddToken(kw.CreateToken(col, line));
                    continue;
                }
                //識別子・キーワード
                if ((lm = IdentiferPattern.Match(source)).Success && lm.Index == 0)
                {
                    if ((kw = Keywords.FirstOrDefault(p => lm.Value == p.Item1)) != null)
                    {
                        source = source.Substring(kw.Item1.Length);
                        col += kw.Item1.Length;
                        result.AddToken(kw.CreateToken(col, line));
                    }
                    else
                    {
                        source = source.Substring(lm.Length);
                        col += lm.Length;
                        result.AddToken(lm.Value.CreateTokenAsIdentifer(col, line));
                    }
                    continue;
                }
                //リテラル
                if ((lm = BinaryNumberPattern.Match(source)).Success && lm.Index == 0)
                {
                    source = source.Substring(lm.Length);
                    col += lm.Length;
                    result.AddToken(lm.Value.CreateTokenAsBinaryNumber(col, line));
                    if (!(lm = IdentiferPattern.Match(source)).Success || lm.Index != 0) continue;
                }
                if ((lm = OctadecimalNumberPattern.Match(source)).Success && lm.Index == 0)
                {
                    source = source.Substring(lm.Length);
                    col += lm.Length;
                    result.AddToken(lm.Value.CreateTokenAsOctadecimalNumber(col, line));
                    if (!(lm = IdentiferPattern.Match(source)).Success || lm.Index != 0) continue;
                }
                if ((lm = HexadecimalNumberPattern.Match(source)).Success && lm.Index == 0)
                {
                    source = source.Substring(lm.Length);
                    col += lm.Length;
                    result.AddToken(lm.Value.CreateTokenAsHexadecimalNumber(col, line));
                    if (!(lm = IdentiferPattern.Match(source)).Success || lm.Index != 0) continue;
                }
                if ((lm = HexatridecimalNumberPattern.Match(source)).Success && lm.Index == 0)
                {
                    source = source.Substring(lm.Length);
                    col += lm.Length;
                    result.AddToken(lm.Value.CreateTokenAsHexatridecimalNumber(col, line));
                    if (!(lm = IdentiferPattern.Match(source)).Success || lm.Index != 0) continue;
                }
                if ((lm = DecimalNumberPattern.Match(source)).Success && lm.Index == 0)
                {
                    source = source.Substring(lm.Length);
                    col += lm.Length;
                    result.AddToken(lm.Value.CreateTokenAsDecimalNumber(col, line));
                    if (!(lm = IdentiferPattern.Match(source)).Success || lm.Index != 0) continue;
                }
                if ((cq = StringQuotation.FirstOrDefault(p => source.StartsWith(p))) != null)
                {
                    source = source.Substring(cq.Length);
                    col += cq.Length;
                    int qp = 0, eqp = 0, inp = 0;
                    var ls = "";
                    do
                    {
                        eqp = source.IndexOf("\\" + cq);
                        qp = source.IndexOf(cq);
                        inp = source.IndexOf(Environment.NewLine);
                        if (inp >= 0 && inp < qp)
                        {
                            ei = new KecaknoahError
                            {
                                Column = col,
                                Line = line,
                                Message = "文字列リテラル中に直接改行が含まれています。改行を表現したい場合、\\nを利用してください。"
                            };
                            result.Error = ei;
                            result.Success = false;
                            return result;
                        }
                        if (qp < 0)
                        {
                            ei = new KecaknoahError
                            {
                                Column = col,
                                Line = line,
                                Message = "文字列リテラルが閉じていません。"
                            };
                            result.Error = ei;
                            result.Success = false;
                            return result;
                        }
                        if (eqp >= 0 && qp - eqp == 1)
                        {
                            ls += source.Substring(0, qp + cq.Length);
                            source = source.Substring(qp + cq.Length);
                            col += qp + cq.Length - 1;
                            continue;
                        }
                        else
                        {
                            ls += source.Substring(0, qp);
                            source = source.Substring(qp + cq.Length);
                            foreach (var i in StringLiteralEscapes) ls = ls.Replace(i.Item1, i.Item2);
                            result.AddToken(new KecaknoahToken { Position = new Tuple<int, int>(col, line), TokenString = ls, Type = KecaknoahTokenType.StringLiteral });
                            col += qp + cq.Length;
                            break;
                        }
                    } while (true);
                    continue;
                }
                //不明
                ei = new KecaknoahError
                {
                    Column = col,
                    Line = line,
                    Message = "不正なトークンです。"
                };
                result.Error = ei;
                result.Success = false;
                return result;
            }
            result.Success = true;
            return result;
        }
    }