Ejemplo n.º 1
0
        /// <summary>
        /// ソース名とソースを指定して解析します。
        /// </summary>
        /// <param name="name">ソース名</param>
        /// <param name="source">解析対象のソースコード</param>
        /// <returns></returns>
        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;
        }
Ejemplo n.º 2
0
 internal KecaknoahException(KecaknoahError err) : base($"解析中にエラーが発生しました: {err.Message}")
 {
     Error = err;
 }
Ejemplo n.º 3
0
        /// <summary>
        /// ソース名とソースを指定して解析します。
        /// </summary>
        /// <param name="name">ソース名</param>
        /// <param name="source">解析対象のソースコード</param>
        /// <returns></returns>
        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);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// 規定
 /// </summary>
 /// <param name="message">メッセージ</param>
 /// <param name="inner">内側</param>
 public KecaknoahParseException(string message, Exception inner) : base(message, inner)
 {
     Error = new KecaknoahError { Column = 0, Line = 0, Message = message };
 }
Ejemplo n.º 5
0
 /// <summary>
 /// 指定した<see cref="KecaknoahError"/>を格納して初期化します。
 /// </summary>
 /// <param name="error">エラー情報</param>
 public KecaknoahParseException(KecaknoahError error) : base(error.Message)
 {
     Error = error;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// 規定のコンストラクター
 /// </summary>
 public KecaknoahParseException()
 {
     Error = new KecaknoahError { Column = 0, Line = 0, Message = "" };
 }